PHP ソースコード ext/mysql 拡張部分
Jun 13, 2016 pm 12:23 PM
私は外部モジュール拡張機能を作成しましたが、PHP ソース コード內(nèi)の mysql 拡張機能を調(diào)べ始めています。これは PHP に統(tǒng)合できるため、組み込み拡張機能と見なす必要があります。
この拡張機能は、mysql データベースによって提供されるいくつかのインターフェイスを使用する必要があるため、mysql をインストールし、mysql.h の場所を決定する必要があります。
この拡張機能の場所は通常、PHP-source-code/ext/mysql の下にあります。
Linux では、注意が必要な主なファイルは config.m4、php_mysql.c、php_mysql_structs.h です。
ps: このディレクトリにはタグ ファイルがあるため、ctags のさまざまな機能を使用して関數(shù)やマクロ定義などを直接検索できます。
追記: Linux sudo mysql-dir/bin/mysqld_safe &
で mysql を起動すると、2 つのプロセスが実行されます:
コードをコピーコードは次のとおりです:
root 5297 0.0 0.0 5920 1416 pts/5 S 11:08 0:00 /bin/sh /usr/local/mysql/bin/mysqld_safe
mysql 5320 1.4 1.1 202728 23796 ポイント/5 Sl 11:08 1:47 /usr/local/mysql/libexec/mysqld --basedir=/usr/local/mysql --datadir=/usr/local/mysql/var --user= mysql -- pid-file=/usr/local/mysql/var/tj1clnxweb0004.pid --skip-external-locking --port=3306 --socket=/tmp/mysql.sock
--- --------------------------------------------------- -
最初に以下の読み取り値を記録します。 プロセスの詳細(xì):
1. php_mysql_do_query_general 関數(shù)
この拡張機能によって提供される関數(shù) mysql_query および mysql_unbuffered_query は、最終的に php_mysql_do_query_general を使用してコア関數(shù)を?qū)g行します。
最初にトレース モードを確認(rèn)します:
if (MySG(trace_mode)) { .... }
php.ini に設(shè)定があります:
mysql.trace_mode = Off
そして if configured が open の場合は if 內(nèi)の文が実行され、実行された文が select の場合は SQL 文のパフォーマンスを分析するために前に Explain が追加されます。
次に、mysql_use_result と mysql_store_result の違いを見てみましょう。
ご覧のとおり、mysql_query は mysql_store_result 関數(shù)を使用し、mysql_unbuffered_query は mysql_use_result を使用します。
記事 (http://school.cnd8.com/mysql/jiaocheng/25143_8.htm) を參照して、次のように要約します。
mysql_store_result はクエリを?qū)g行してすべての結(jié)果セットを取得し、それらをクライアントに保存します。クライアントで使用するためにそれらを準(zhǔn)備します。これには、クライアントでより多くのメモリとパフォーマンスが必要です。
mysql_use_result はクエリのみを?qū)g行しますが、結(jié)果の取得が遅れます。これは、サービス フロントエンドで結(jié)果セットを維持することと同じです。
mysql_store_result を呼び出し、mysql_fetch_row を使用して結(jié)果を取得した後、戻り値が NULL の場合、結(jié)果はクライアントから直接取得されます。
mysql_use_result が呼び出され、mysql_fetch_row を使用して結(jié)果が取得される場合、結(jié)果が NULL の場合、結(jié)果は役に立たないか、ネットワーク接続エラーまたはその他の理由がある可能性があります。
結(jié)果セットのメンテナンス場所が異なるため、mysql_store_result の結(jié)果は、任意のシーク、合計數(shù)の取得、非順次アクセスなど、より多くの処理機能を提供できます。 mysql_use_result の結(jié)果セットは使用できません。
さらに、mysql_use_result の結(jié)果セットはサーバー側(cè)で維持されるため、クライアントは結(jié)果セット內(nèi)の各行に対して mysql_fetch_row を呼び出す必要があるという要件が提示されます。そうしないと、結(jié)果セット內(nèi)の殘りのレコードが結(jié)果セットになります。次のクエリ結(jié)果がセットの一部であるため、「非同期」エラーが発生します。
それでは、なぜ mysql_use_result を使用する必要があるのでしょうか?この狀況を見てください:
mysql と mysqldump はデフォルトで mysql_store_result を使用しますが、 --quick オプションが指定されている場合は、mysql_use_result が使用されます。
ということは、mysql_use_result は効率の點で有利ということですか?
mysql ヘルプ マニュアルを參照してください:
-q、--quick 結(jié)果をキャッシュせず、行ごとに出力します。これにより、出力が一時停止されると、
サーバーの速度が低下する可能性があります。
履歴ファイル。
Mysqldump ヘルプ マニュアル:
-q、--quick クエリをバッファせず、stdout に直接ダンプします。
なぜ、quick が mysql_use_result に対応するのかがよくわかりません。これを行うには、まず mysql_use_result を使用しない場合を判斷します。 mysql_use_result の結(jié)果セットはサーバー側(cè)で保持されるため、クライアントプログラムがハングする可能性がある場合は使用しないでください。結(jié)果セット內(nèi)の行間に操作が多すぎる場合は、これを使用しないでください。言い換えれば、クエリが完了し、結(jié)果がすぐに使い盡くされて解放されない場合は、mysql_use_result を使用しないでください。
効果を試すために、次のテスト コードを書きました:
コードをコピーします コードは次のとおりです:
$sql = sprintf ("select * from pet;");
$result = mysql_unbuffered_query($sql, $conn);
$rows = mysql_fetch_row($result);行);
$ sql = sprintf("ショップから * を選択");
$rows = mysql_fetch_row($result); ($rows);
実行の結(jié)果、2 回目のフェッチでは最初の結(jié)果は表示されませんが、PHP は次の通知を報告します。
PHP 通知: mysql_unbuffered_query(): 前のバッファリングされていないクエリから最初にすべての行をフェッチせずに関數(shù)が呼び出されました。 /home/yicheng/test-all/mysqltest/test.php 28 行目
テスト コードを変更します:
コードをコピーします コードは次のとおりです
$i = 1000000;
while($i--){
$sql = sprintf("select * from pet;"); mysql_query($sql, $conn);
#$result = mysql_unbuffered_query($sql, $conn);
while($rows = mysql_fetch_row($result)){
}
if ($result) {
mysql_free_result($result);
}
}
:!time ./test.php
real 1m10.220s
user 0m17.853s
sys 0m9.541s
mysql_query の使用結(jié)果:
:!time ./test.php
real 1m11.191s
user 0m19.297s
sys 0m10.133s
時間差は大きくないようです
2. いくつかのリソース関連のマクロ定義
コードをコピーします コードは次のとおりです。
#define ZEND_VERIFY_RESOURCE(rsrc)
if (!rsrc) {
RETURN_FALSE;
}
#define ZEND_FETCH_RESOURCE( rsrc、rsrc_type、passed_id、default_id、resource_type_name、resource_type)
rsrc = (rsrc_type) zend_fetch_resource(passed_id TSRMLS_CC、default_id、resource_type_name、NULL、1、resource_type);
ZEND_VERIFY_RESOURCE(rsrc); OURCE2 (rsrc、rsrc_type、passed_id、default_id、resource_type_name、resource_type1、resource_type2)
rsrc = (rsrc_type) zend_fetch_resource(passed_id TSRMLS_CC、default_id、resource_type_name、NULL、2、resource_type1、resource_type2);
ZEND_VERIFY_RESOURCE(rsrc);
#define ZEND_REGISTER_RESOURCE(rsrc_result, rsrc_pointer, rsrc_type)
zend_register_resource(rsrc_result, rsrc_pointer, rsrc_type);
#define ZEND_GET_RESOURCE_TYPE_ID(le_id, le_type_name)
if (le_id == 0) ) {
le_id = zend_fetch_list_dtor_id(le_type_name);
}
mysql_connect 関數(shù)から返されるものは、実際にはマッピング可能なリンク ID (タイプ (mysql link) の resource(4)) です。 ZEND_FETCH_RESOURCE および ZEND_FETCH_RESOURCE2 マクロを通じて、対応する mysql リソースにアクセスします。どちらのマクロも zend_fetch_resource メソッドを呼び出しますので、このメソッドを見てみましょう。
たとえば、mysql_list_dbs 関數(shù)で ZEND_FETCH_RESOURCE2 マクロを呼び出します。
ZEND_FETCH_RES OURCE2(mysql , php_mysql_conn *, mysql_link, id, "MySQL-Link", le_link, le_plink);
ここで、mysql は返された有効なリソースを保存します。php_mysql_conn * は返されたリソースのタイプを定義します。mysql_link、id は、passed_id に対応します。それぞれdefault_id (多くの関數(shù)呼び出しは特定のconnを渡さないため、単にデフォルト値を使用します)、「MySQL-Link」はresource_type_name、le_link、le_plinkはzend_fetch_resourceの部分であり、両方とも靜的intです。値を入力します。
zend_fetch_resource からわかるように、タイプ (mysql リンク) の resource(4) の value.lval には長いタイプ ID が含まれています。 default_id が -1 の場合は、passed_id によって渡された ID が使用され、それ以外の場合は、default_id が ID として使用され、対応するリソースの検索に zend_list_find が使用されます。
いくつかの関數(shù)を見た後、この拡張機能は mysql によって提供される c インターフェイスをカプセル化したものにすぎないことがわかりました。しかし、パッケージは非常に標(biāo)準(zhǔn)化されており、安定しています。
さらに詳しく知りたい場合は、やはり MYSQL のソース コードを參照する必要があります。いくつかの重要なデータ構(gòu)造を以下に示します。
----------------------------------------
チェックに関するいくつかの質(zhì)問エラーは役に立つ php 関數(shù)である可能性があります:
コードをコピー コードは次のとおりです:
error_reporting(E_ALL); #var_dump(mysql_get_host_info($conn));#var_dump(mysql_get_proto_info($conn));
#var_dump(mysql_stat($conn)); ??># var_dump(mysql_errno($conn));
#var_dump(mysql_error($conn));
--- ---------------------------------------------------
MYSQL ソース コードのいくつかの便利な構(gòu)造體
コードは次のとおりです:
typedef struct st_mysql
{
NET net; /* 通信パラメータ */
gptr Connector_fd; /* ConnectorFd for SSL */
char *host,*user,*passwd,*unix_socket,*server_version,*host_info,*info;
char *db;
struct charset_info_st *charset;
MYSQL_FIELD *フィールド;
MEM_ROOT フィールド_alloc;
my_ulonglongaffected_rows;
my_ulonglong insert_id; /* NEXTNR を使用してテーブルに挿入する場合の ID */
my_ulonglong extra_info; /* 使用されません */
unsigned long thread_id; /* サーバーの接続用の ID */
unsigned long packet_length;
符號なし int ポート;
unsigned long client_flag,server_capabilities;
unsigned int プロトコルバージョン;
unsigned int field_count;
unsigned int server_status;
unsigned int サーバー言語;
unsigned int warning_count;
struct st_mysql_options オプション;
列挙型 mysql_status ステータス;
my_bool free_me; /* mysql_close で空いている場合 */
my_bool 再接続; /* 自動再接続の場合は 1 に設(shè)定 */
/* セッション全體のランダムな文字列 */
char scramble[SCRAMBLE_LENGTH 1];
/*
これが元の接続であり、
mysql_rpl_probe() または mysql_set_master()/ mysql_add_slave() によって追加したマスターまたはスレーブではない場合に設(shè)定します
*/
my_bool rpl_pivot ;
/*
マスターへのポインタ、および次のスレーブ接続は、単獨の接続の場合は
それ自體を指します。
*/
struct st_mysql* マスター、*next_slave;
struct st_mysql* last_used_slave; /* ラウンドロビンのスレーブ選択に必要 */
/* レプリケーションで正しく動作するために結(jié)果の送信/読み取り/保存/使用に必要 */
struct st_mysql* last_used_con;
LIST *stmts; /* すべてのステートメントのリスト */
const struct st_mysql_methods *methods;
void *thd;
/*
MYSQL_RES または MYSQL_STMT のブール型フラグを指します。 close がこのオブジェクトの結(jié)果セットをキャンセルする必要がある場合は、mysql_stmt_close からこのフラグを
に設(shè)定します。
*/
my_bool *unbuffered_fetch_owner;
#定義されている場合(EMBEDDED_LIBRARY) ||定義済み(EMBEDDED_LIBRARY_COMPATIBLE) || MYSQL_VERSION_ID >= 50100
/* 組み込みサーバーに必要 - 「情報」を保存するためのネット バッファーがありません */
char *info_buffer;
#endif
} MYSQL;
typedef struct st_mysql_methods
{
my_bool (*read_query_result)(MYSQL *mysql);
my_bool (*advanced_command)(MYSQL *mysql,
enum enum_server_command コマンド,
const char *header,
unsigned long header_length,
const char *arg,
unsigned long arg_length,
my_bool Skip_check、
MYSQL_STMT *stmt);
MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
unsigned int フィールド);
MYSQL_RES * (*use_result)(MYSQL *mysql);
void (*fetch_lengths)(unsigned long *to,
MYSQL_ROW カラム, unsigned int field_count);
void (*flush_use_result)(MYSQL *mysql);
#if !define(MYSQL_SERVER) ||定義済み(EMBEDDED_LIBRARY)
MYSQL_FIELD * (*list_fields)(MYSQL *mysql);
my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
int (*stmt_execute)(MYSQL_STMT *stmt);
int (*read_binary_rows)(MYSQL_STMT *stmt);
int (*unbuffered_fetch)(MYSQL *mysql, char **row);
void (*free_embedded_thd)(MYSQL *mysql);
const char *(*read_statistics)(MYSQL *mysql);
my_bool (*next_result)(MYSQL *mysql);
int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd);
int (*read_rows_from_cursor)(MYSQL_STMT *stmt);
#endif
} MYSQL_METHODS;

ホットAIツール

Undress AI Tool
脫衣畫像を無料で

Undresser.AI Undress
リアルなヌード寫真を作成する AI 搭載アプリ

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

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中國語版
中國語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統(tǒng)合開発環(huán)境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

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

n 1クエリの問題を避け、関連するデータを事前にロードすることにより、データベースクエリの數(shù)を減らします。 2.必要なフィールドのみを選択して、メモリと帯域幅を保存するために完全なエンティティをロードしないようにします。 3. DoctrineのセカンダリキャッシュやRedis Cacheの高周波クエリ結(jié)果など、キャッシュ戦略を合理的に使用します。 4.エンティティのライフサイクルを最適化し、クリア()を定期的に呼び出してメモリを解放してメモリオーバーフローを防ぎます。 5.データベースインデックスが存在し、生成されたSQLステートメントを分析して、非効率的なクエリを避けます。 6.変更が不要なシナリオで自動変更追跡を無効にし、パフォーマンスを改善するためにアレイまたは軽量モードを使用します。 ORMを正しく使用するには、SQLモニタリング、キャッシュ、バッチ処理、適切な最適化を組み合わせて、開発効率を維持しながらアプリケーションのパフォーマンスを確保する必要があります。

settings.jsonファイルは、ユーザーレベルまたはワークスペースレベルのパスにあり、VSCODE設(shè)定のカスタマイズに使用されます。 1。ユーザーレベルのパス:WindowsはC:\ users \\ appdata \ roaming \ code \ user \ settings.json、macos is/users //settings.json、linux is /home/.config/code/user/settings.json; 2。Workspace-Level Path:.vscode/settings Project Root Directoryの設(shè)定

PHPのゴミ収集メカニズムは參照カウントに基づいていますが、周期的な円形のゴミコレクターによって円形の參照を処理する必要があります。 1。変數(shù)への參照がない場合、參照カウントはすぐにメモリを解放します。 2.參照參照により、メモリを自動的にリリースできなくなり、GCを検出およびクリーニングすることがGCに依存します。 3。GCは、「可能なルート」ZVALがしきい値に到達するか、GC_COLLECT_CYCLES()を手動で呼び出すとトリガーされます。 4.長期実行PHPアプリケーションは、メモリの漏れを避けるために、gc_status()を監(jiān)視し、gc_collect_cycles()を呼び出す必要があります。 5.ベストプラクティスには、gc_disable()を使用してパフォーマンスキー領(lǐng)域を最適化し、ormのclear()メソッドを介して繰り返しのオブジェクトを最適化する回路參照の回避が含まれます。

BREFにより、PHP開発者は、サーバーを管理せずにスケーラブルで費用対効果の高いアプリケーションを構(gòu)築できます。 1.Brefは、最適化されたPHPランタイムレイヤーを提供し、PHP8.3およびその他のバージョンをサポートし、LaravelやSymfonyなどのフレームワークとシームレスに統(tǒng)合することにより、PHPをAwslambdaにもたらします。 2。展開手順には、次のものが含まれます。Composerを使用してBREFのインストール、httpエンドポイントや職人コマンドなどの関數(shù)とイベントを定義するためにserverless.ymlの構(gòu)成。 3. serverlessdeployコマンドを?qū)g行して、展開を完了し、Apigatewayを自動的に構(gòu)成し、アクセスURLを生成します。 4。Lambdaの制限については、Brefは解決策を提供します。

readonlypropertiesinphp8.2canonlybeassignedonedonedontheconstructoraturatiddeclaration andcannotBemodifiedifiedifiedifiedifiedifiedifiedifiadtivedabilityattthelanguagelele.2.

usearestapitobridgephpandmlmodelsbyrunningthemodelinpythonviaflaskorapiandapiandcallingtfromphpusingcurlorguzzle.2.runpythosscriptsdirectlyfrompurspusingec()orshell_exec()

まず、JavaScriptを使用して、ユーザーシステムの設(shè)定とローカルに保存されたテーマ設(shè)定を取得し、ページテーマを初期化します。 1. HTML構(gòu)造には、トピックの切り替えをトリガーするボタンが含まれています。 2。CSSの使用:rootは明るいテーマ変數(shù)を定義し、.dark-modeクラスは暗いテーマ変數(shù)を定義し、これらの変數(shù)をvar()を介して適用します。 3. JavaScript検出は、カラーのスchemeを好み、LocalStorageを読み取り、最初のテーマを決定します。 4.ボタンをクリックするときにHTML要素のダークモードクラスを切り替え、現(xiàn)在の狀態(tài)をLocalStorageに保存します。 5.すべての色の変更には、ユーザーを強化するために0.3秒の移行アニメーションが伴います

パフォーマンス分析ツールを使用してボトルネックを見つけ、開発とテスト段階でVisualVMまたはJProfilerを使用し、生産環(huán)境で非同期財産を優(yōu)先します。 2。オブジェクトの作成を削減し、オブジェクトを再利用し、StringBuilderを使用して文字列のスプライシングを置き換え、適切なGC戦略を選択します。 3.コレクションの使用を最適化し、シーンに応じて初期容量を選択し、プリセットします。 4.同時性を最適化し、同時コレクションを使用し、ロックの粒度を低減し、スレッドプールを合理的に設(shè)定します。 5. JVMパラメーターを調(diào)整し、合理的なヒープサイズと低遅延のゴミコレクターを設(shè)定し、GCログを有効にします。 6.コードレベルでの反射を避け、ラッパークラスを基本タイプに置き換え、初期化を遅延させ、最終と靜的を使用します。 7。JMHと組み合わせた連続性能テストと監(jiān)視
