ホームページ php教程 php手册 解析数组非数字键名引号的必要性

解析数组非数字键名引号的必要性

Jun 13, 2016 am 11:42 AM
いいえ 必要性 操作する 番号 配列 解析する キー名 いいえ

我看到过很多人操作数组的时候, 对于数组中的非数字键名不使用引号

复制代码 代码如下:


  $array[key] = $value;


我可以理解有些人可能会觉得这样的代码很”整洁”, 并且也能正常执行.
更甚至,如果他很”幸运的”php配置的好:

复制代码 代码如下:


error_reporting = ~E_NOTIC


他也许永远都沉浸在自己的”整洁”风格中, 看不到任何的NOTICE提示, 也不会意识到, 他这么做, 能损失多少的性能~
来, 我们一起来看看:
good.php:

复制代码 代码如下:


   $array = array();
   $i = 0;
   while(++$i        $array['good'] = 2;
   }
?>


bad.php:

复制代码 代码如下:


   $array = array();
   $i = 0;
   while(++$i        $array[good] = 2;
   }
?>


分别看运行时间(多次平均时间):
加引号的:

复制代码 代码如下:


$ time php -f good.php
real 0m0.013s
user 0m0.005s
sys 0m0.007


不加引号的:

复制代码 代码如下:


$ time php -f bad.php
PHP Notice: Use of undefined constant bad - assumed 'bad' in /home/huixinchen/tmp/bad.php
on line (此处省略999行NOTICE)
real 0m0.100s
user 0m0.020s
sys 0m0.029


看看,差别有多大?
哦, 或许我们应该模拟一下那些”幸运的”人们的情况, 去掉花费在记录NOTICE的开销, 看看~

复制代码 代码如下:


$ time php -f bad.php
real 0m0.037s
user 0m0.018s
sys 0m0.018


我们可以看出, 基本上, 使用引号,和不使用引号的效率损失在3倍以上
那么, 这些效率损失到哪里去了呢?
我们分别看下, 俩个文件生成的OPCODE序列:
good.php :

复制代码 代码如下:


filename: /home/huixinchen/tmp/good.php
compiled vars: !0 = $array, !1 = $i
line # op fetch ext return operands
-------------------------------------------------------------------------------
   2 0 INIT_ARRAY ~0
         1 ASSIGN !0, ~0
   3 2 ASSIGN !1, 0
   4 3 PRE_INC $3 !1
         4 IS_SMALLER ~4 $3, 1000
         5 JMPZ ~4, ->9
   5 6 ZEND_ASSIGN_DIM !0, 'good'
         7 ZEND_OP_DATA 2, $6
   6 8 JMP ->3
   8 9 RETURN 1
        10* ZEND_HANDLE_EXCEPTIO


bad.php :

复制代码 代码如下:


filename: /home/huixinchen/tmp/bad.php
compiled vars: !0 = $array, !1 = $i
line # op fetch ext return operands
-------------------------------------------------------------------------------
   2 0 INIT_ARRAY ~0
         1 ASSIGN !0, ~0
   3 2 ASSIGN !1, 0
   4 3 PRE_INC $3 !1
         4 IS_SMALLER ~4 $3, 1000
         5 JMPZ ~4, ->10
   5 6 FETCH_CONSTANT ~5 'bad'
         7 ZEND_ASSIGN_DIM !0, ~5
         8 ZEND_OP_DATA 2, $7
   6 9 JMP ->3
   8 10 RETURN 1
        11* ZEND_HANDLE_EXCEPTIO


我们可以看出(其实,根据NOTICE的提示也知道), PHP会把没有引号引起来的键名当作是常量去获取, 当找不到的时候, 抛出一个NOTICE, 然后再根据”常量明”生成一个字符串, 然后再讲这个字符串做为键名继续~
聪明的你一定会想到, 可能会出现如下不可预期的错误:

复制代码 代码如下:


define('key_name' , 'laruence');
....
//省略很多行代码
$array[key_name] = 2; //变成了 $array['laruence'] = 2;
//这样的错误, 你会很郁闷吧?


明白了么? 数组中的非数字键的键名一定要有引号啊~
哦, 还记得有人会说, 那在字符串变量替换的时候, 写引号会导致错误,
恩, 标准写法:

复制代码 代码如下:


$string = "variable value is {$array['key']}"


我很赞同:”be lazy”, 但是, lazy也是应该有原则的.
最后, 好的代码,不应该通过关闭error_reporting来伪装.
附注, FETCH_CONSTANT OPCODE中找不到常量的相关逻辑:

复制代码 代码如下:


....
if (!zend_get_constant(opline->op2.u.constant.value.str.val,
     opline->op2.u.constant.value.str.len, &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) {
       zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
                opline->op2.u.constant.value.str.val,
                opline->op2.u.constant.value.str.val);
       EX_T(opline->result.u.var).tmp_var = opline->op2.u.constant;//获取"常量"名字符串
       zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);//分配空间,生成字符串
}
....

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHP 配列キー値の反転: さまざまな方法のパフォーマンス比較分析 PHP 配列キー値の反転: さまざまな方法のパフォーマンス比較分析 May 03, 2024 pm 09:03 PM

PHP の配列キー値の反転メソッドのパフォーマンスを比較すると、array_flip() 関数は、大規模な配列 (100 万要素以上) では for ループよりもパフォーマンスが良く、所要時間が短いことがわかります。キー値を手動で反転する for ループ方式は、比較的長い時間がかかります。

PHP 配列ディープ コピーの技術: さまざまな方法を使用して完璧なコピーを実現する PHP 配列ディープ コピーの技術: さまざまな方法を使用して完璧なコピーを実現する May 01, 2024 pm 12:30 PM

PHP で配列をディープ コピーする方法には、json_decode と json_encode を使用した JSON エンコードとデコードが含まれます。 array_map と clone を使用して、キーと値のディープ コピーを作成します。シリアル化と逆シリアル化には、serialize と unserialize を使用します。

PHP 配列の多次元ソートの実践: 単純なシナリオから複雑なシナリオまで PHP 配列の多次元ソートの実践: 単純なシナリオから複雑なシナリオまで Apr 29, 2024 pm 09:12 PM

多次元配列のソートは、単一列のソートとネストされたソートに分類できます。単一列のソートでは、array_multisort() 関数を使用して列ごとにソートできますが、ネストされたソートでは、配列を走査してソートするための再帰関数が必要です。具体的な例としては、製品名による並べ替えや、売上数量や価格による化合物の並べ替えなどがあります。

PHP 配列のディープ コピーのベスト プラクティス: 効率的な方法を発見する PHP 配列のディープ コピーのベスト プラクティス: 効率的な方法を発見する Apr 30, 2024 pm 03:42 PM

PHP で配列のディープ コピーを実行するためのベスト プラクティスは、 json_decode(json_encode($arr)) を使用して配列を JSON 文字列に変換し、それから配列に戻すことです。 unserialize(serialize($arr)) を使用して配列を文字列にシリアル化し、それを新しい配列に逆シリアル化します。 RecursiveIteratorIterator を使用して、多次元配列を再帰的に走査します。

データソートにおけるPHP配列グループ化機能の応用 データソートにおけるPHP配列グループ化機能の応用 May 04, 2024 pm 01:03 PM

PHP の array_group_by 関数は、キーまたはクロージャ関数に基づいて配列内の要素をグループ化し、キーがグループ名、値がグループに属する要素の配列である連想配列を返すことができます。

重複要素の検索における PHP 配列グループ化関数の役割 重複要素の検索における PHP 配列グループ化関数の役割 May 05, 2024 am 09:21 AM

PHP の array_group() 関数を使用すると、指定したキーで配列をグループ化し、重複する要素を見つけることができます。この関数は次の手順で動作します。 key_callback を使用してグループ化キーを指定します。必要に応じて、value_callback を使用してグループ化値を決定します。グループ化された要素をカウントし、重複を特定します。したがって、array_group() 関数は、重複する要素を見つけて処理するのに非常に役立ちます。

Astar ステーキングの原則、収入の解体、エアドロップ プロジェクトと戦略、および運営のナニー レベルの戦略 Astar ステーキングの原則、収入の解体、エアドロップ プロジェクトと戦略、および運営のナニー レベルの戦略 Jun 25, 2024 pm 07:09 PM

目次 Astar Dapp ステーキングの原則 ステーキング収益 潜在的なエアドロップ プロジェクトの解体: AlgemNeurolancheHealthreeAstar Degens DAOVeryLongSwap ステーキング戦略と運用 「AstarDapp ステーキング」は今年初めに V3 バージョンにアップグレードされ、ステーキング収益に多くの調整が加えられましたルール。現在、最初のステーキング サイクルが終了し、2 番目のステーキング サイクルの「投票」サブサイクルが始まったばかりです。 「追加報酬」特典を獲得するには、この重要な段階を把握する必要があります (6 月 26 日まで続く予定で、残りは 5 日未満です)。 Astarステーキング収入を詳しく説明します。

PHP 配列重複排除アルゴリズムの複雑さを調べる PHP 配列重複排除アルゴリズムの複雑さを調べる Apr 28, 2024 pm 05:54 PM

PHP 配列重複排除アルゴリズムの複雑さ: array_unique(): O(n) array_flip()+array_keys(): O(n) foreach ループ: O(n^2)

See all articles