PHP變數和函數的特異功能
動態變數 Variable variables
剛接觸PHP的人一定會覺得很奇怪,會什麼變數(variables)前面都要帶$
為什麼不像 java 或者其他語言,變數名直接拿來用呢?
後來才知道 PHP 支援 Dynamic variables動態變數 i.e variable variables的功能。
例子:
<?php
$hello = 'world';
$world = 'hello';
echo $$world . "\n"; //output: world
PHP 會把 ${$world}
的值拿出來替換,因此變數成為 $hello
,所以 output就是 'world' 字串。但太多的$...$
轉換會造成代碼理解的困難。
請不要寫出下列的代碼:
後面維護的人員應該會想罵人吧~~
何時使用動態變數
- for-loop 中最常使用到動態變數,例如下面的例子:
<?php
// price name list
$priceNameList = array('Original', 'VIP', 'Employee');
// price list
$priceList = array(300, 200, 100);
$total = count($priceList);
// dump priceList to meaningful variable name;
for ($i=0; $i < $total; $i++) {
${'price'.$priceNameList[$i]} = $priceList[$i];
}
echo 'oringial price: ' . $priceOriginal . "\n";
這樣就可以將變數的名稱做有意義的命名,當然也可以透過 array key value的方式做到。
$priceDictionary = array("Original" => 300,
"VIP" => 200,
"Employee" => 100);
foreach ($priceDictionary as $key => $value) {
${'price'.$key} = $value;
}
echo 'demo 2: oringial price: ' . $priceOriginal . "\n";
更進階的方法,PHP中提供了一個很特別的函式extract()
,只要一行就可以做到我們的需求:
extract($priceDictionary, EXTR_PREFIX_ALL, "price");
echo 'demo 3: oringial price: ' . $price_Original . "\n";
這裡需要特別注意的地方是,extract()
參數,預設值是 EXTR_OVERWRITE
,會把既有變數的值覆蓋。另外 EXTR_PREFIX_ALL
變數會有 _
i.e $price_Original
而不是 $priceOriginal
。
有關extract()參數請參考 extract manual
動態函式 Variable functions
這也是PHP中神奇的功能,當變數後面接著parentheses()
,PHP編譯程式會去試著執行這函式。
但PHP原生功能(language constructs) 像是 echo, print, unset(), isset(), empty(), include, require等等,動態函式不會生效。範例如下
<?php
namespace StudyGroup\LanguageFeatures\PHPClass;
class Foo
{
public static $fun = 'static property';
public static function fun()
{
echo 'Method fun called' . "\n";
}
public function hello()
{
echo 'Hello world!' . "\n";
}
}
echo Foo::$fun . "\n"; // This prints 'static property'. It does need a $fun in this scope.
$fun = 'fun';
Foo::$fun(); // This calls $foo->fun() reading $fun in this scope.
Namespaces 和 動態語言一起使用
如果變數後面接著parentheses()
,前面也有 new
時,PHP 會嘗試去生成物件,如下面的程式碼:
<?php
namespace StudyGroup\LanguageFeatures\PHPClass;
class Foo
{
public static $fun = 'static property';
public static function fun()
{
echo 'Method fun called' . "\n";
}
public function hello()
{
echo 'Hello world!' . "\n";
}
}
$className = __NAMESPACE__ . '\\' . 'Foo'; // need to add name space
$methodName = 'hello';
$myFoo = new $className();
$myFoo->$methodName();
請注意:一定要指定 NAMESPACE
即使PHP Class宣告在同一個檔案內。不然會得到下面的Fatal Error錯誤訊息:
Fatal error: Uncaught Error: Class 'Foo' not found in /Users/user/Dev/PHP7StudyGroup/src/LanguageFeatures/PHPClass/DemoVariableFunctions.php:24
主要的原因是當使用動態變數Variable functions
沒有加上Namespace時,PHP會找Global的class。請參考