ホームページ バックエンド開発 PHPチュートリアル 二重引用符が多すぎるかどうか、それが問題です。

二重引用符が多すぎるかどうか、それが問題です。

Aug 16, 2024 pm 04:34 PM

つい最近、PHP 関係者が依然として一重引用符と二重引用符について話しており、一重引用符の使用は単なる微細な最適化であるが、常に一重引用符を使用することに慣れていれば、大量の CPU を節約できるということを再び聞きました。サイクル!

「すべてはすでに言われていますが、まだ誰もが言っていません」 – カール・ヴァレンティン

私はこの精神に基づいて、ニキータ・ポポフがすでに 12 年前に書いたのと同じテーマについて記事を書いています (彼の記事を読んでいる場合は、ここで読むのをやめても構いません)。

ファズとは一体何でしょうか?

PHP は文字列補間を実行し、文字列内で使用されている変数を検索し、使用されている変数の値に置き換えます。

$juice = "apple";
echo "They drank some $juice juice.";
// will output: They drank some apple juice.
ログイン後にコピー

この機能は、二重引用符で囲まれた文字列およびヒアドキュメントに限定されます。一重引用符 (または nowdoc) を使用すると、別の結果が得られます:

$juice = "apple";
echo 'They drank some $juice juice.';
// will output: They drank some $juice juice.
ログイン後にコピー

見てください: PHP はその一重引用符で囲まれた文字列内の変数を検索しません。したがって、どこでも一重引用符を使用し始めることができます。そこで人々はこのような変更を提案し始めました ..

- $juice = "apple";
+ $juice = 'apple';
ログイン後にコピー

.. なぜなら、PHP は一重引用符で囲まれた文字列 (この例には存在しません) 内の変数を検索しないため、より高速になり、そのコードを実行するたびに大量の CPU サイクルを節約できるからです。全員が幸せになり、事件は解決しました。

事件は解決しましたか?

一重引用符の使用と二重引用符の使用には明らかに違いがありますが、何が起こっているのかを理解するには、もう少し深く掘り下げる必要があります。

PHP はインタープリター型言語ですが、仮想マシンが実際に実行できるもの (オペコード) を取得するために特定の部分が連携するコンパイル ステップを使用しています。では、PHP ソースコードからオペコードにどのようにしてアクセスできるのでしょうか?

レクサー

レクサーはソース コード ファイルをスキャンし、トークンに分割します。これが何を意味するのかについての簡単な例は、token_get_all() 関数のドキュメントに記載されています。

T_OPEN_TAG (<?php )
T_ECHO (echo)
T_WHITESPACE ( )
T_CONSTANT_ENCAPSED_STRING ("")
ログイン後にコピー
ログイン後にコピー

この 3v4l.org スニペットで実際の動作を確認し、試してみることができます。

パーサー

パーサーはこれらのトークンを受け取り、そこから抽象構文ツリーを生成します。上記の例の AST 表現を JSON として表すと次のようになります。

{
  "data": [
    {
      "nodeType": "Stmt_Echo",
      "attributes": {
        "startLine": 1,
        "startTokenPos": 1,
        "startFilePos": 6,
        "endLine": 1,
        "endTokenPos": 4,
        "endFilePos": 13
      },
      "exprs": [
        {
          "nodeType": "Scalar_String",
          "attributes": {
            "startLine": 1,
            "startTokenPos": 3,
            "startFilePos": 11,
            "endLine": 1,
            "endTokenPos": 3,
            "endFilePos": 12,
            "kind": 2,
            "rawValue": "\"\""
          },
          "value": ""
        }
      ]
    }
  ]
}
ログイン後にコピー

これも試して、他のコードの AST がどのように見えるかを確認したい場合は、Ryan Chandler による https://phpast.com/ と https://php-ast-viewer.com/ を見つけました。どちらも、特定の PHP コード部分の AST を表示します。

コンパイラ

コンパイラは AST を取得し、オペコードを作成します。オペコードは仮想マシンが実行するものであり、OPcache を設定して有効にしている場合 (これを強くお勧めします)、OPcache に保存されるものでもあります。

オペコードを表示するには、複数のオプションがあります (おそらくもっとあるかもしれませんが、私はこれら 3 つを知っています)。

  1. vulcan ロジック ダンパー拡張機能を使用します。 3v4l.org にも焼き付けられています
  2. phpdbg -p script.php を使用してオペコードをダンプします
  3. または、OPcache の opcache.opt_debug_level INI 設定を使用して、オペコードを出力するようにします。
    • 値 0x10000 は、最適化前のオペコードを出力します
    • 値 0x20000 は、最適化後にオペコードを出力します
$ echo '<?php echo "";' > foo.php
$ php -dopcache.opt_debug_level=0x10000 foo.php
$_main:
...
0000 ECHO string("")
0001 RETURN int(1)




</p>
<h2>
  
  
  仮説
</h2>

<p>一重引用符と二重引用符を使用するときに CPU サイクルを節約するという最初のアイデアに戻ると、これが成り立つのは、PHP が単一のリクエストごとに実行時にこれらの文字列を評価する場合に限られるということに誰もが同意すると思います。</p>

<h2>
  
  
  実行時に何が起こるのでしょうか?
</h2>

<p>それでは、PHP が 2 つの異なるバージョンに対してどのオペコードを作成するかを見てみましょう。</p>

<p>二重引用符:<br>
</p>

<pre class="brush:php;toolbar:false"><?php echo "apple";
ログイン後にコピー
0000 ECHO string("apple")
0001 RETURN int(1)
ログイン後にコピー
ログイン後にコピー

vs.一重引用符:

<?php echo 'apple';
ログイン後にコピー
0000 ECHO string("apple")
0001 RETURN int(1)
ログイン後にコピー
ログイン後にコピー

ちょっと待って、何か奇妙なことが起こりました。これは同じに見えます!私のマイクロ最適化はどこへ行ったのでしょうか?

そうですね、おそらく、ECHO オペコード ハンドラーの実装は指定された文字列を解析しますが、そうするように指示するマーカーやその他のものはありません...うーん?

別のアプローチを試して、これら 2 つのケースに対してレクサーが何を行うかを見てみましょう:

二重引用符:

T_OPEN_TAG (<?php )
T_ECHO (echo)
T_WHITESPACE ( )
T_CONSTANT_ENCAPSED_STRING ("")
ログイン後にコピー
ログイン後にコピー

vs.一重引用符:

Line 1: T_OPEN_TAG (<?php )
Line 1: T_ECHO (echo)
Line 1: T_WHITESPACE ( )
Line 1: T_CONSTANT_ENCAPSED_STRING ('')
ログイン後にコピー

トークンは依然として二重引用符と一重引用符を区別していますが、AST をチェックすると、両方のケースで同じ結果が得られます。唯一の違いは、Scalar_String ノード属性の rawValue であり、一重引用符と二重引用符がまだ含まれていますが、どちらの場合も、値には二重引用符が使用されます。

新しい仮説

文字列補間は実際にはコンパイル時に行われる可能性はありますか?

もう少し「洗練された」例で確認してみましょう:

<?php
$juice="apple";
echo "juice: $juice";
ログイン後にコピー

このファイルのトークンは次のとおりです:

T_OPEN_TAG (<?php)
T_VARIABLE ($juice)
T_CONSTANT_ENCAPSED_STRING ("apple")
T_WHITESPACE ()
T_ECHO (echo)
T_WHITESPACE ( )
T_ENCAPSED_AND_WHITESPACE (juice: )
T_VARIABLE ($juice)
ログイン後にコピー

Look at the last two tokens! String interpolation is handled in the lexer and as such is a compile time thing and has nothing to do with runtime.

Too double quote or not, that

For completeness, let's have a look at the opcodes generated by this (after optimisation, using 0x20000):

0000 ASSIGN CV0($juice) string("apple")
0001 T2 = FAST_CONCAT string("juice: ") CV0($juice)
0002 ECHO T2
0003 RETURN int(1)
ログイン後にコピー

This is different opcode than we had in our simple

Get to the point: should I concat or interpolate?

Let's have a look at these three different versions:

<?php
$juice = "apple";
echo "juice: $juice $juice";
echo "juice: ", $juice, " ", $juice;
echo "juice: ".$juice." ".$juice;
ログイン後にコピー
  • the first version is using string interpolation
  • the second is using a comma separation (which AFAIK only works with echo and not with assigning variables or anything else)
  • and the third option uses string concatenation

The first opcode assigns the string "apple" to the variable $juice:

0000 ASSIGN CV0($juice) string("apple")
ログイン後にコピー

The first version (string interpolation) is using a rope as the underlying data structure, which is optimised to do as little string copies as possible.

0001 T2 = ROPE_INIT 4 string("juice: ")
0002 T2 = ROPE_ADD 1 T2 CV0($juice)
0003 T2 = ROPE_ADD 2 T2 string(" ")
0004 T1 = ROPE_END 3 T2 CV0($juice)
0005 ECHO T1
ログイン後にコピー

The second version is the most memory effective as it does not create an intermediate string representation. Instead it does multiple calls to ECHO which is a blocking call from an I/O perspective so depending on your use case this might be a downside.

0006 ECHO string("juice: ")
0007 ECHO CV0($juice)
0008 ECHO string(" ")
0009 ECHO CV0($juice)
ログイン後にコピー

The third version uses CONCAT/FAST_CONCAT to create an intermediate string representation and as such might use more memory than the rope version.

0010 T1 = CONCAT string("juice: ") CV0($juice)
0011 T2 = FAST_CONCAT T1 string(" ")
0012 T1 = CONCAT T2 CV0($juice)
0013 ECHO T1
ログイン後にコピー

So ... what is the right thing to do here and why is it string interpolation?

String interpolation uses either a FAST_CONCAT in the case of echo "juice: $juice"; or highly optimised ROPE_* opcodes in the case of echo "juice: $juice $juice";, but most important it communicates the intent clearly and none of this has been bottle neck in any of the PHP applications I have worked with so far, so none of this actually matters.

TLDR

String interpolation is a compile time thing. Granted, without OPcache the lexer will have to check for variables used in double quoted strings on every request, even if there aren't any, waisting CPU cycles, but honestly: The problem is not the double quoted strings, but not using OPcache!

However, there is one caveat: PHP up to 4 (and I believe even including 5.0 and maybe even 5.1, I don't know) did string interpolation at runtime, so using these versions ... hmm, I guess if anyone really still uses PHP 5, the same as above applies: The problem is not the double quoted strings, but the use of an outdated PHP version.

Final advice

Update to the latest PHP version, enable OPcache and live happily ever after!

以上が二重引用符が多すぎるかどうか、それが問題です。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、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衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の 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での安全なパスワードハッシュ(例:Password_hash、password_verify)を説明します。 MD5またはSHA1を使用してみませんか? PHPでの安全なパスワードハッシュ(例:Password_hash、password_verify)を説明します。 MD5またはSHA1を使用してみませんか? Apr 17, 2025 am 12:06 AM

PHPでは、Password_hashとpassword_verify関数を使用して安全なパスワードハッシュを実装する必要があり、MD5またはSHA1を使用しないでください。 1)password_hashセキュリティを強化するために、塩値を含むハッシュを生成します。 2)password_verifyハッシュ値を比較して、パスワードを確認し、セキュリティを確保します。 3)MD5とSHA1は脆弱であり、塩の値が不足しており、最新のパスワードセキュリティには適していません。

PHPとPython:2つの一般的なプログラミング言語を比較します PHPとPython:2つの一般的なプログラミング言語を比較します Apr 14, 2025 am 12:13 AM

PHPとPythonにはそれぞれ独自の利点があり、プロジェクトの要件に従って選択します。 1.PHPは、特にWebサイトの迅速な開発とメンテナンスに適しています。 2。Pythonは、データサイエンス、機械学習、人工知能に適しており、簡潔な構文を備えており、初心者に適しています。

PHP:Web開発の重要な言語 PHP:Web開発の重要な言語 Apr 13, 2025 am 12:08 AM

PHPは、サーバー側で広く使用されているスクリプト言語で、特にWeb開発に適しています。 1.PHPは、HTMLを埋め込み、HTTP要求と応答を処理し、さまざまなデータベースをサポートできます。 2.PHPは、ダイナミックWebコンテンツ、プロセスフォームデータ、アクセスデータベースなどを生成するために使用され、強力なコミュニティサポートとオープンソースリソースを備えています。 3。PHPは解釈された言語であり、実行プロセスには語彙分析、文法分析、編集、実行が含まれます。 4.PHPは、ユーザー登録システムなどの高度なアプリケーションについてMySQLと組み合わせることができます。 5。PHPをデバッグするときは、error_reporting()やvar_dump()などの関数を使用できます。 6. PHPコードを最適化して、キャッシュメカニズムを使用し、データベースクエリを最適化し、組み込み関数を使用します。 7

アクション中のPHP:実際の例とアプリケーション アクション中のPHP:実際の例とアプリケーション Apr 14, 2025 am 12:19 AM

PHPは、電子商取引、コンテンツ管理システム、API開発で広く使用されています。 1)eコマース:ショッピングカート機能と支払い処理に使用。 2)コンテンツ管理システム:動的コンテンツの生成とユーザー管理に使用されます。 3)API開発:RESTFUL API開発とAPIセキュリティに使用されます。パフォーマンスの最適化とベストプラクティスを通じて、PHPアプリケーションの効率と保守性が向上します。

スカラータイプ、リターンタイプ、ユニオンタイプ、ヌル可能なタイプなど、PHPタイプのヒントはどのように機能しますか? スカラータイプ、リターンタイプ、ユニオンタイプ、ヌル可能なタイプなど、PHPタイプのヒントはどのように機能しますか? Apr 17, 2025 am 12:25 AM

PHPタイプは、コードの品質と読みやすさを向上させるためのプロンプトがあります。 1)スカラータイプのヒント:php7.0であるため、基本データ型は、int、floatなどの関数パラメーターで指定できます。 3)ユニオンタイプのプロンプト:PHP8.0であるため、関数パラメーターまたは戻り値で複数のタイプを指定することができます。 4)Nullable Typeプロンプト:null値を含めることができ、null値を返す可能性のある機能を処理できます。

PHPの永続的な関連性:それはまだ生きていますか? PHPの永続的な関連性:それはまだ生きていますか? Apr 14, 2025 am 12:12 AM

PHPは依然として動的であり、現代のプログラミングの分野で重要な位置を占めています。 1)PHPのシンプルさと強力なコミュニティサポートにより、Web開発で広く使用されています。 2)その柔軟性と安定性により、Webフォーム、データベース操作、ファイル処理の処理において顕著になります。 3)PHPは、初心者や経験豊富な開発者に適した、常に進化し、最適化しています。

PHPおよびPython:コードの例と比較 PHPおよびPython:コードの例と比較 Apr 15, 2025 am 12:07 AM

PHPとPythonには独自の利点と短所があり、選択はプロジェクトのニーズと個人的な好みに依存します。 1.PHPは、大規模なWebアプリケーションの迅速な開発とメンテナンスに適しています。 2。Pythonは、データサイエンスと機械学習の分野を支配しています。

PHP対その他の言語:比較 PHP対その他の言語:比較 Apr 13, 2025 am 12:19 AM

PHPは、特に迅速な開発や動的なコンテンツの処理に適していますが、データサイエンスとエンタープライズレベルのアプリケーションには良くありません。 Pythonと比較して、PHPはWeb開発においてより多くの利点がありますが、データサイエンスの分野ではPythonほど良くありません。 Javaと比較して、PHPはエンタープライズレベルのアプリケーションでより悪化しますが、Web開発により柔軟性があります。 JavaScriptと比較して、PHPはバックエンド開発により簡潔ですが、フロントエンド開発のJavaScriptほど良くありません。

See all articles