iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 10
0

compact

在第一章提到的 Online PHP Functions網站,
因為安全性因素所以不提供執行這個函式。

這個函式可以在執行當下的空間,建立一個包含你指定的變數(以及它的值)的陣列。

比如像下面原本要用六行才能把所有參數打包成一個陣列的動作,
使用這個函式的話一行就能搞定了!

<?php

function collectRequestParams ($method, $uri, $body, $params)
{
    return [
        'method' => $method,
        'uri' => $uri,
        'body' => $body,
        'params' => $params
    ];
}

上面的寫法等同下面的

<?php

function collectRequestParams ($method, $uri, $body, $params)
{
    return compact('method', 'uri', 'body', 'params');
}

上面的寫法等同下面的

<?php

function collectRequestParams ($method, $uri, $body, $params)
{
    return compact(['method', 'uri', 'body', 'params']);
}

上面的寫法等同下面的

<?php

function collectRequestParams ($method, $uri, $body, $params)
{
    return compact(explode(' ', 'method uri body params'));
}

可以這樣做的原理是,compact的參數其實也吃陣列,該陣列參數包含所有你需要打包的變數的名稱。
而正好可以利用 explode 把所需變數寫在一個 string 裡面,
並轉換成包含變數名稱的陣列給compact使用。

參考自 M Spreij 的留言

extract

這個函式剛好是相反的功能。
它可以幫你把關聯陣列中的 elements 按照其原本的鍵值對(key-value pair)形式放進當下的作用域。

<?php

$response = [
    'status' => 'OK',
    'message' => 'Upload succeeded',
    'data' => [
        'url' => 'https://www.youtube.com/watch?v=W7YT0ZUcTU8'
    ],
];

function extractResponse ($data)
{
    extract($data);
    
    if ($status !== 'OK') {
        throw new \Exception('Upload failed');
    }
    
    return $data;
}

print_r(extractResponse($response));

第二個參數:決定已存在同名變數時的行為

有時候你也可能遇到這樣的狀況,
幸好這個函式可以透過預先定義的一些常數改變它的行為。

比如下面這段改寫自上面範例的程式碼:
$data 已經被宣告成一組包含 1 到 10 的序列,
但在使用帶有 EXTR_OVERWRITEextract 之後,
原本的 $data 就會被來自 $response 的 data 覆蓋過去。

注意!其實在任何不指定第二個參數的時候,這個函式都會直接覆蓋已存在的同名變數!

<?php

$response = [
    'status' => 'OK',
    'message' => 'Upload succeeded',
    'data' => [
        'url' => 'https://www.youtube.com/watch?v=W7YT0ZUcTU8'
    ],
];

$data = range(1, 10);

extract($response, EXTR_OVERWRITE);

print_r($data);

第三個參數:前綴

當你指定的第二個參數是下列其中之一:

  1. EXTR_PREFIX_SAME (如果有衝突,在變數的名稱前加上前綴。 )
  2. EXTR_PREFIX_ALL (在所有變數的名稱前加上前綴。)
  3. EXTR_PREFIX_INVALID (僅在非法/數字的變量名稱前加上前綴。 )
  4. EXTR_PREFIX_IF_EXISTS (僅在目前作用域中已有同名變數時,覆蓋它們的值。...更多點此

也就是在遇到有衝突的時候,第三個參數才有意義。
因為也許你打算讓新舊同名參數共存(但不可能),所以你只好讓新變數加上前綴。

要注意的是,它會自動在指定的前綴,與變數名中間加上底線!

<?php

$response = [
    'status' => 'OK',
    'message' => 'Upload succeeded',
    'data' => [
        'url' => 'https://www.youtube.com/watch?v=W7YT0ZUcTU8'
    ],
];

$data = range(1, 10);

extract($response, EXTR_PREFIX_ALL, 'pre');

echo $pre_status . PHP_EOL;
echo $pre_message . PHP_EOL;

上一篇
Array:用語統一
下一篇
Object:Pass By Reference By Default
系列文
花式PHP31

尚未有邦友留言

立即登入留言