低価格・高品質・最速のHTMLコーディングはクロノドライブへ

wordpressの$query_stringからデータベース接続までの三千里

エンジニアリング部エンジニアリング課のひよっこエンジニアKと申します。最近私はwordpressについて勉強しているのですが、ふとその中で$query_stringという変数に出会いました。今回の記事では、$query_stringがどんな変数なのかと、それを知るにあたって私が調べた、$query_stringを使って記事を取得するコードを書いてから、データベースから$query_stringで指定された記事が引っ張ってこられて表示されるまでの三千里(嘘)の道のりをご紹介しようと思います。

 

今回$query_stringを使ったコード

今回私が$query_stringのコードを使ったページはarchive.phpのページでした。

$query_stringをここでvar_dumpすると、

var_dump($query_string);

出力は以下の通りになりました。
[そのページがカテゴリーのアーカイブページの場合]

string(75) "category_name=%25e3%2582%25ab%25e3%2583%2586%25e3%2582%25b4%25e3%2583%25aa1"

[そのページが月別アーカイブページの場合]
string(21) "year=2019&monthnum=09"
そのページがカテゴリーのアーカイブページの時は、category_nameというキーにその値が、そのページが月間アーカイブページの時は、yearというキーとmonthnumというキーにそれぞれ値が入っていることがわかります。

結局$query_stringでやってたことってなんだったの?

今回$query_stringを使ったコードで、$query_stringを使って何をやっていたのか?を簡単に言うと、wp_title関数から取得した値を配列に変換し、表示する記事の条件を指定する一部を担っていた、となります。上記のページではparse_str関数を使い、$query_stringで指定した条件と$argsで指定した条件を$argsにまとめ、その$argsによってWP_Queryのインスタンスを生成することでデータベースから希望の条件をすべて満たした記事を引っ張ってきて表示していました。

今回の旅のゴール地点

今回の旅の最終地点は、どうやって変数$query_stringからSQL文が形成され、データベースからデータを持ってきているかの全貌を明らかにすることです。なので、以下の順に処理を追って、データベースに接続している箇所とデータベースにどうクエリを渡しているかを明らかにします。
①まず取得された値を文字列として変数に格納している箇所を探す
②文字列と文字列をくっつけてSQL文の文字列にしている箇所を探す
③データベース接続して、SQL文をデータベース側に渡している箇所を探す

$query_stringからデータベースへの接続までの三千里

①$query_stringに入っていた値を変数に格納する

まず$query_stringに入っていた値を変数に格納します。今回WP_Queryのインスタンスを生成しているときにデータベースに接続がなされていたようだったので(SQLログを調べました)、WP_Queryのクラス定義をしているファイルの中で、$query_stringに入っていた値を変数に渡している箇所がないか探しました。すると、

という辺りで年月の値が渡っていることが明らかになりました。どうやらここでまずは値を変数に格納しているようです。

②文字列と文字列をくっつけてSQL文にする

その後、$data_parametersという変数の定義を見てみると、

というような処理を見つけます。ここで$whereをvar_dumpしてみると、なんとSQLログで見たことのある文字列の一部が…!どうやらここでSQL文の切れ端が作られていたみたいです。

この$whereを使ってSQL文の形の文字列を作っている箇所がないか探すと…

$this->request = $old_request = "SELECT $found_rows $distinct $fields FROM {$wpdb->posts} $join WHERE 1=1 $where $groupby $orderby $limits";

なんと、めちゃくちゃSQLのSELECT文の文字列を作ってそうな場所にめぐりあいました。

③データベース接続して、SQL文をデータベース側に渡す

その後、この$this->requestを使ってデータベース接続してそうな場所がないか探します。すると、ちょっと気になる箇所が出てきました。

$ids = $wpdb->get_col( $this->request );

この$idsをvar_dumpすると、記事更新日時が新しい順の、$query_stringで指定した条件に当てはまる記事IDが5件出力されます。ということは、$idsに代入された時点では、もうデータベース接続に成功しています。つまり、それ以前にデータベース接続をしているということがわかります。$idsに代入される直前にあたるのは、$wpdbか、get_col()になります。まずは$wpdbの方を見てみましょう。

 $wpdbとデータベース接続

$wpdbはWordPressのグローバル変数の一つで、今までのファイルとは違うload.phpに定義があります。さっそく定義箇所を見てみましょう。

最後でデータベース接続におなじみのDB_USERなどを使ったインスタンスが生成されていることがわかります。あともう一息!

wpdbというインスタンスを生成していたので、今度はwpdbというクラスの定義を探してみます。すると、wp-db.phpというファイルの、wpdbクラスのコンストラクタでこんな記述を見つけました。

どうやら、$this->db_connect();の部分でデータベース接続を行っていそうです!db_connect関数の定義の一部を見てみると、

このselectという関数を使って、データベースを選択していそうなことがわかります。

実際、select関数の定義を調べてみると、mysqli_select_db関数でデータベースの選択を行っています。

ということは、やはりこの段階でデータベースに接続を行っていそうです。これでWordPressがどういう経緯でデータベースを接続していたか、全貌が明らかになりましたね。

get_col()とクエリ

めでたくデータベース接続の流れを解き明かせた次は、get_col()を使ってどうクエリを渡しているのかを見ていきましょう。さっそくget_col()の定義を確認してみます。

この中で、$queryをvar_dumpしてみると、②の段階で見つけたSQLのSELECT文の切れ端を含むSELECT文が出力されました。一方で$this->last_resultや$new_arrayをvar_dumpしてみると、指定の記事IDが取得されてきていることがわかります。つまり、query関数を実行している辺りでデータベースにクエリが渡っていそうなことがわかります。さっそくquery関数の定義を見てみましょう。

$this->last_query = $query;直後でvar_dumpしてみると、まだすべてのSQL文が文字列として表示されています。 一方で、その後は$this->insert_id = mysqli_insert_id( $this->dbh );など、クエリを実行した結果に対しての返り値を変数に代入している部分が存在します。ということは、$this->last_query = $query;以下で少なくとも文字列がデータベース上に入り、実行されていることがわかります。さっそく$this->last_query = $query;直後に実行される、_do_query関数を見てみましょう。

定義の中をよく見てみると、mysqli_query関数がありました。この関数はデータベース上でクエリを実行する関数です。つまり、この時点でまさにクエリが実行され、データベースからデータを取得してきたということがわかりました。

今回のまとめ

①$query_stringでは、取ってくる記事を指定する条件の一部を担っている

②$query_stringからデータベース接続までの流れは、値を変数に代入→値を使った文字列をどんどん他の文字列とつなぎ合わせていく→データベースにそのクエリを引き渡してデータを貰ってくるの3段階になっている

③グローバル変数$wpdbによってデータベース接続が、(今回は)get_col関数によってデータベースにクエリが引き渡されている

 

「フロントエンドエンジニアの教科書」を出版しました!HTML・CSS・JavaScript+α 次世代コーダーのための仕事術

HTMLコーダーからフロントエンドエンジニアにステップするために必要な知識と技術を解説。
現場で求められる人材となるためには、何を知っていて、何ができなければいけないのか。
Web制作の最先端にいるクロノドライブだからこそ教えられるノウハウが満載です。

出版社名:ソフトバンククリエイティブ
著者:クロノドライブ

Amazon.co.jp詳細ページへ