問題タブ [php-internals]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
php - PHP オペコードは、実際に実行されたバイナリ コードとどのように関連していますか?
プレーンテキストとしての test.php:
オペコードとしてのtest.php:
バイナリ表現としての test.php:
(test.php のエコー出力をスキップ)
ここで、オペコードがバイナリ表現にどのように変換されるかについて詳しく知りたいと思います。
編集され明確化された質問:
オペコードはどのようにバイナリ バージョンに変換されますか? 'a' から !0 への ASSIGN が表示されているのがわかりますか? ECHOステートメントとそれが出力するものはどこかにありますか?
オペコードの行ごとの表現を暗示するバイナリ バージョンのパターンはほとんど見つかりませんでした。
(「2f726f6f742f746573742e706870」は「/root/test.php」の 16 進数表現です)
編集:
行の長さを 4 バイトに設定し、異なるプログラム間で比較すると、16 進表現でパターンが明らかになります。
しかし、仮想マシンがそのようなレベルでどのように機能するかについての私の知識は、それを適切に分析して C コードにリンクすることができないほど貧弱です。
編集:
php - PHPで「シンボル」/「変数名」が作成されるのはいつですか?
これは私の設定です:
display_startup_errors = on
display_errors = on
error_reporting = E_ALL | E_STRICT
上記のコード行は、zval コンテナーを作成し、それをシンボル a' に関連付けます。そして、次のo / pを提供します。
次のコードを検討してください。
o/p を生成します。
PHPマニュアルの参照カウントの基本から:定数値で新しい変数が作成されると、zvalコンテナーが作成されます
これはつまり、
1] code2 の 1 行目と同様のコードが発生した場合、シンボルは作成されません
$a;
。xdebug_debug_zval はシンボル/変数名「a」を見つけられないため。Reference Counting Basicsのステートメントによると、 zval コンテナーは作成されません。
2] シンボルは、code2 の 3 行目と同様のコード$a = "abcd";
に遭遇した場合にのみ作成されます。つまり、変数が定数値に関連付けられている場合にのみシンボルが作成され、参照カウントの基本のステートメントに従って、zval コンテナーが作成され、シンボル 'a' に関連付けられます。そして、code2 ie の 1 行目$a;
は役に立たないコードです。
xdebug_debug_zval の詳細については、こちらをご覧ください。
php - array_keysはどのように値を検索しますか?
PHPのarray_keysはどのように値を検索しますか?
例:
それらはキーと値のペアであるため。PHPは、配列内の各キーペアを反復処理するのではなく、ハッシュに基づいて検索を実行すると推測しています。
これに関する「明確な考え」はありますか?
この質問に触発された質問:同じサイズの配列内の対応する要素が数値(反復なし)である場合、配列内の空の要素のキーを取得するにはどうすればよいですか?
php - 「new」でインスタンス化するときに正確に何が起こっているのですか?
次のコードを考えてみましょう。
出力:
$obj1 へのインスタンス化後:
obj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=2, is_ref=0)=NULL }$obj->var1 に「Hello」を割り当てた後:
Helloobj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=1, is_ref=0)='Hello ' }
一つずつ:
$obj1 へのインスタンス化後:
obj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=2, is_ref=0)=NULL }
クラス a のオブジェクトが 1 つしかないのに、なぜ$obj1->var1
haveがあるのですか?refcount=2
new
オペレーターが割り当てを行う方法のためですか?PHP は参照を使用して代入を行います。でインスタンス化するとnew
、シンボル/変数名はそのインスタンスに関連付けられません。ただし、クラス プロパティには名前があります。これのrecount=2
せいでしょうか?
その場合は、クラス インスタンスの浅いコピー WRT で COW (コピー オン ライト) が発生しています。プロパティは、 を使用してインスタンス化中に作成されたプロパティの zval をまだ指していますnew
。
今、
$obj->var1 に「Hello」を割り当てた後:
Helloobj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=1, is_ref=0)='Hello ' }
そのため、プロパティに値を割り当てると、そのプロパティ$obj1->var1
の新しい zval コンテナ、したがってrefcount=1
?
これは、インスタンス化中に作成された zval コンテナがnew
まだ生きているが、シンボル/変数名が関連付けられていないためアクセスできないことを意味しますか?
注意してください ( xdebug: Variable Display Featuresより):
debug_zval_dump()
は とは異なりxdebug_debug_zval()
ます。
void xdebug_debug_zval( [文字列変数名 [, ...]] )
変数に関する情報を表示します。
この関数は、型、値、および参照カウント情報を含む、1 つ以上の変数に関する構造化された情報を表示します。配列は、値を使用して再帰的に探索されます。この関数は、変数自体が実際に関数に渡されるために、PHP の debug_zval_dump() 関数が持つ問題を回避するために、PHP のdebug_zval_dump()関数とは異なる方法で実装されています。Xdebug のバージョンは、変数名を使用して内部シンボル テーブル内の変数を検索し、関数に変数を実際に渡す必要なく、すべてのプロパティに直接アクセスするため、より優れています。その結果、この関数が返す情報は、zval 情報を表示するための PHP 独自の関数よりもはるかに正確です。
UPDATE
:Dec 31th 2011:
newが使用されたときにメモリ割り当てがどのように行われるかを調べようとしています。でも、今しなければならないことは他にもたくさんあります。すぐに有益なアップデートを投稿できることを願っています。それまでは、私が見ていたコードへのリンクを次に示します。
php - 'プロパティへの書き込み'/'クラスのオブジェクトへのプロパティの注入'時にCOWが発生しないのはなぜですか?
出力:
echo1:インスタンス化後:
t1:(refcount = 1、is_ref = 0)= class a {public $ test =(refcount = 2、is_ref = 0)='msg1'}echo2:$t1を$t2に割り当てた後:
t2:(refcount = 2、is_ref = 0)= class a {public $ test =(refcount = 2、is_ref = 0)='msg1'}echo3:$ t1-> test = "msg2"を割り当てた後:
t1:(refcount = 2、is_ref = 0)= class a {public $ test =(refcount = 1、is_ref = 0)='msg2'}
t2 :( refcount = 2、is_ref = 0)= class a {public $ test =(refcount = 1、is_ref = 0)='msg2'}echo4:$ t2-> test = "msg3"を割り当てた後:
t1:(refcount = 2、is_ref = 0)= class a {public $ test =(refcount = 1、is_ref = 0)='msg3'}
t2 :( refcount = 2、is_ref = 0)= class a {public $ test =(refcount = 1、is_ref = 0)='msg3'}echo5:$test2を$t2に注入した後:
t1:(refcount = 2、is_ref = 0)= class a {public $ test =(refcount = 1、is_ref = 0)='msg3'; public $ test2 =(refcount = 1、is_ref = 0)='c ap!' }
t2:(refcount = 2、is_ref = 0)= class a {public $ test =(refcount = 1、is_ref = 0)='msg3'; public $ test2 =(refcount = 1、is_ref = 0)='c ap!' }
無視してこれが原因: 「new」でインスタンス化するecho1
と、正確に何が起こっているのでしょうか。&期待される動作。echo2
検討中echo3
:
echo3:$ t1-> test = "msg2"を割り当てた後:
t1:(refcount = 2、is_ref = 0)= class a {public $ test =(refcount = 1、is_ref = 0)='msg2'}
t2 :( refcount = 2、is_ref = 0)= class a {public $ test =(refcount = 1、is_ref = 0)='msg2'}
$t1->test
変数を変更するだけで、に直接変更することはないので、これは理解でき&t2->test
ます。
を考慮echo4
して、への直接変更$t2->test
が行われる場所:
echo4:$ t2-> test = "msg3"を割り当てた後:
t1:(refcount = 2、is_ref = 0)= class a {public $ test =(refcount = 1、is_ref = 0)='msg3'}
t2 :( refcount = 2、is_ref = 0)= class a {public $ test =(refcount = 1、is_ref = 0)='msg3'}
COWは発生しません!$t1
設定されていなくても、変更はに反映されis_ref
ます。
を考えるecho5
と、変数$test2
はに注入され$t2
ます:
echo5:$test2を$t2に注入した後:
t1:(refcount = 2、is_ref = 0)= class a {public $ test =(refcount = 1、is_ref = 0)='msg4'; public $ test2 =(refcount = 1、is_ref = 0)='c ap!' }
t2:(refcount = 2、is_ref = 0)= class a {public $ test =(refcount = 1、is_ref = 0)='msg4'; public $ test2 =(refcount = 1、is_ref = 0)='c ap!' }
繰り返しますが、COWは発生しません!$t1
設定されていなくても、変更はに反映されis_ref
ます。
Why is this behaviour!?
php - とは #オブジェクトのvar_dumpのobject(someClass)の隣にありますか?推論があります。私は正しいですか?
これは、以下の推論を描くために使用したコードとその出力です。
出力:
オブジェクトの行の#<some-number>
隣は実際object(someClass)
にはです。どこ、var_dump
#<count>
countは、これまでに作成されたオブジェクトが属するクラスに関係なく、オブジェクトのオブジェクト/ zvalの数です。これは、作成されたすべてのオブジェクトに対してインクリメントを続け、zvalのrefcountがゼロに達すると1ずつデクリメントされます。つまり、ガベージコレクションです。
私は正しいですか?
php - PHP拡張機能から関数をオーバーロードするには?
PHP 拡張機能のチュートリアルをいくつか行ってきましたが、既存の関数をオーバーロードする方法に関する情報が見つかりません。
たとえば、 fopen() を次のように変更したい
どうすればそれができますか?ありがとうございました
PS。私は拡張子を意味します(Cで書かれ、.soにコンパイルされ、.phpプログラムではなくhttpd.confに含まれています)
編集:Gordon リンクのおかげで解決策が見つかりました。
function の PECL パッケージをダウンロードしましrename_function
た。そのソースコードは、必要な結論に私を導きました:
function_table
名前に基づいて、関数のすべてのポインターを保持するグローバルハッシュテーブルがあります。zend_hash_find
//これにより、このテーブルで必要な変更を行うことができますzend_hash_add
。zend_hash_del
php - PHP 拡張機能: zend_hash_update を使用してクラス フィールドを更新できません
このクラスをphp拡張機能に実現したい:
__constructor、$attrs フィールド、および __get メソッドは既に実装しています。そして今、私は__setについて理解できません。
私のCコードがあります:
attrs - init 関数で保護されたプロパティを宣言しました (プロパティを null として宣言しましたが、コンストラクターで $attrs にデータを追加すると、プロパティは配列に更新されます)
私の質問は次のとおりです。Cでattrフィールドを更新するにはどうすればよいですか? 私の拡張機能は正常にコンパイルされ、プロパティを定義して読み取ることができますが、設定することはできません-設定された値がnullになるためです。例:
私はC開発が初めてで、本当に助けが必要です.
UPD 1. __set body をこれに変更しようとしました:
これで、文字列値を設定できるようになりました。各タイプの zval を切り替える必要がある場合は??
php - file_get_contents が memcache_get より速いのはなぜですか?
file_get_contents を使用してディスクから XML ファイルをロードしています。テストの結果file_get_contents()
、3.99 秒で 1,000 回を使用して 156K ファイルをロードできることがわかりました。読み込みを行う部分をサブクラス化し、memcache レイヤーに置き換えました。私の開発マシンでは、同じドキュメントを 4.54 秒で 1000 回読み込むことができることがわかりました。
file_get_contents() がキャッシングを行うのはありがたいのですが、よく知られているキャッシング技術よりも実際には速いようです。1 台のサーバーで、 のパフォーマンスはfile_get_contents()
最高ですか?
Macports、OS X 10.6.8経由でPHP 5.2.17を使用しています。
MEMCACHE_COMPRESSED
編集: このサイズの XML ドキュメントで見つけたのですが、フラグを使用することには小さな利点があります。memcache を介した 1,500 の読み込みは、6.74 秒 (圧縮なし) ではなく、6.44 秒 (圧縮あり) で実行されます。ただし、どちらも より遅くfile_get_contents
、5.71 秒で同じ数の読み込みを行います。
php - 拡張機能から「ネイティブ」PHP オブジェクトを返す
個人的なプロジェクト用のPHP 拡張機能の作成に手を出しています。上記の記事にリンクされている内容を超えて、私は zend_engine についての知識がありません。私の C スキルは 10 年前のものであり、学問的な知識しかありませんでした。これらはすべて、「ばかげた質問をしているように見える場合は、おそらくそうです」と言うものです。
自分の拡張機能で他の PHP 拡張機能から関数を呼び出すことは可能ですか? それとも、各 PHP 拡張機能は島と見なされ、システムの他の部分への洞察はありませんか? これが可能である場合、それは一般的な慣行ですか、それとも悪い考えですか?
つまり、このような文字列を返すことができることを知っています。
たとえば、SimpleXML 要素または DomDocument 要素を返すことができるようにしたいと考えています。拡張機能の開発に関する情報はそれほど多くなく、標準的な PHP の使用法に関する情報はたくさんあります。