2017-08-09 45 views
0

我想寫一個函數,將採取任何數量的參數,並將返回第一個參數,按順序,這是有效的(在我的情況!空)。PHP功能級聯通過靈活數量的全/空值

我已經能夠很好地工作,我想如何,除了我因爲未定義的變量而得到一些通知。請參見下面的例子:

function cascade() 
{ 
    if (func_num_args() < 1) return false; 

    foreach (func_get_args() as &$arg) { 
     if (!empty($arg)) return $arg; 
    } 
    return false; 
} 

你可以看到,我試圖宣佈在foreach的每個$arg按引用傳遞,但是這似乎並沒有做的伎倆。

要闡述我計劃如何使用此功能,見下圖:

$a = 'a'; 
$c = 'c'; 

echo cascade($z, $b, $a, $c); 

由於$z$b是不確定的,在列表中的第一個非空的變量是$a所以輸出a預期。然而,你然後得到未定義的變量通知,我想擺脫。

我知道我只能說echo @cascade($z, $b, $a, $c);這將抑制錯誤,但我想知道是否有解決此問題的方法,以便可以通過某種方式傳遞引用。有什麼想法嗎?

編輯:

爲了進一步突出了什麼我想acheive,請參見下面的函數,它的工作沒有引發錯誤,即使通過了未定義的變量:

// returns default value if input variable is not set 
function ifset(&$var, $default = false) { 
    return isset($var) ? $var : $default; 
} 

有了這個函數,如果參數1未設置,則返回參數2中的默認值。無論哪種方式,都不會引發錯誤。

我所試圖實現的是同樣的結果,但隨着參數的任何數量,因爲該功能僅限於1,除非我窩他們(變得混亂)。

現實生活中的例子:

這就是爲什麼我想要這個功能,我將如何使用它在一個真實的生活場景:如果我們有一個訂單

<input type="text" name="customerName" value="<?= cascade($order->fullName, $currentUser->fullName, 'Anonymous') ?>">

所以本作中,並有可從一個名字,我們使用的是,如果該信息有尚未保存,我們使用登錄用戶名作爲默認值,如果沒有人登錄,我們使用「匿名」 。

不正是我會做在現實生活中,但也許它突出例如使用?

對於那些建議定義變量以減輕錯誤的人,這個函數的作用點是通過一系列的值來工作,優先考慮那些先來的,然後轉向下一個,如果這是'空「等,直到最後如果所有內容都爲空,則返回FALSE默認值。

+1

只是聲明$ z,$ b並給它們一個空值,比如'null,「,」,0,..'這是擺脫未定義錯誤的唯一方法,仍按預期工作 – yoeunes

+0

在這種情況下,在傳遞它之前是否有某個原因不會將$ z等定義爲某個空值? – HairMachine

+1

或者使用'echo cascade'($ z ??'',$ b ??'',$ a ??'',$ c ??'');'如果你使用php 7 – yoeunes

回答

0

未定義的變量聲明不是從功能的代碼,但它是從函數調用級聯($ Z,$ B $ A,$ C)

你逝去的不確定變量($ z和$ b)作爲函數的參數。由於它們沒有在代碼中的任何位置進行定義,因此您會收到通知。

爲了擺脫通知,請在將變量作爲參數傳遞之前定義變量。

$a = 'a'; 
$c = 'c'; 
$z = ''; 
$b = ''; 

echo cascade($z, $b, $a, $c); 

OR

echo cascade('', '', $a, $c); 
+0

這是真正的Ravinder,但可以通過引用傳遞該變量,然後檢查它是否已定義或不在函數內部。我現在已經擴展了我的問題,以包含我使用的另一個函數ifset(),它完全是這樣做的,但只有一個變量。 – Marc

0

不知道這是否是 「足夠好」。
創建變量數組並使用數組過濾器刪除空值。
使用數組值來重置鍵。
現在$ arr [0]是第一個非空項目。

https://3v4l.org/PlmrS

$a = 'a'; 
$c = 'c'; 

$arr =array_values(array_filter([$z, $b, $a, $c])); 
Var_dump($arr); 
+0

我仍然得到了錯誤:'通知未定義的變量:z線上6' – yoeunes

+0

@yoeunes所以這是通知是問題?我只是覺得這會比循環更快。但我不明白,這是實際的通知是問題 – Andreas

+0

是的,就是這樣的安德烈亞斯。這是通知,這是問題。函數cascade()實際上工作正常,這是通知是問題。現在我已經包含了另一個類似的函數,它可以在沒有通知的情況下工作,但僅適用於單個變量。 – Marc

1

Notice你看到被觸發,在函數調用,而不是函數本身內。因此,在函數內部無法解決問題。但是,根據變量在函數調用之前的準備方式,有很多解決此問題的方法。

解決方案#1:  定義函數調用之前的變量。

例如:

$z = ''; OR $z = null; 

或像任何falsy值:null, "", 0, "0", 0.0, [], ...,你的功能仍然可以發揮預期的,你不會看到通知。

解決方案2:  在函數調用之前測試合法性。

if(!isset($z)){ $z = ''; } 
echo cascade($z); 

解決方案3:  測試的有效性作爲函數調用的一部分。

這與解決方案#2相同,但稍微優雅一些​​。根據是否設置變量,使用三值函數傳遞變量值或空字符串。

echo cascade(
    isset($z)?$z:'', 
    isset($b)?$b:'', 
    isset($a)?$a:'', 
    isset($c)?$c:'' 
); 

解決方案#4:  如果使用PHP 7或以上,你可以使用新的Null Coalescing Operator。這與解決方案#3相同,但更優雅。顯著

function cascade() 
{ 
    $args = func_get_args(); 

    while (!($arg = array_shift($args))); 

    return $arg ? $arg : false; 
} 

BIG THANKYOUJBH爲編輯這樣的回答:

echo cascade($z ?? '', $b ?? '', $a ?? '', $c ?? ''); 

如果你想要一個乾淨的替代你的功能,你可以試試這個。

+0

這些建議很好,但是這個功能的全部目的是檢查是否設置/空。通過在將它們傳遞給函數之前檢查它們,這會破壞函數的目的。上面提到的 – Marc

+0

,我想要一個相當於echo $ z的函數。 $ b ?? $ a ?? $ c ??假'例如 – Marc

+0

是@Marc我看到你想要達到什麼,但不幸的是你不能用這樣的函數參數來做,只是直接使用像你建議當你移動到PHP 7. ^ – yoeunes

0

謝謝你所有的答案,但不幸的是他們都沒有解決我的問題。也許我沒有很好地解釋它,或者我用過多的信息使問題過度複雜化,但無論如何,我已經能夠找到答案。

以下函數完全符合我的要求。它使用variadic syntax(PHP5.6及以上版本),它允許可變數量的參數,所有參數都通過引用傳遞。

function cascade(&...$args) 
{ 
    if (count($args) < 1) return false; 

    foreach ($args as &$arg) { 
     if (!empty($arg)) return $arg; 
    } 
    return false; 
}