質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

1386閲覧

WordPressにおける、define(アクセスされたURL) の書き方について

ikemen

総合スコア3

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2020/08/12 08:01

編集2020/08/14 14:12

実現したいこと

WordPressでアクセスされたURLを定数として define したいです

その適切な方法を知りたいのですが、最後に記載した【対策1,2,3】はどれにすべきでしょうか
また【よりよい対策】もあれば教えて頂きたいです

よろしくお願い致します!

###発生している問題
アクセスされたURLを次のように define しました
しかし getData で扱おうとすると、最後の行で「$data が見つからないエラーになる!」のです
アクセスしたのはフロントページなので「フロントページの場合の値」がほしいのです
###該当のソースコード

php

1/* 2functions.php 3*/ 4 5// アクセスされた URL を定数にする 6define( 'URL', (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); 7 8// $data を取得する 9function getData(){ 10 11 // アクセスされた URL をもとにページ名 ( $page_name ) を取得する 12 $parsed_url = parse_url( URL ); 13 $path = $parsed_url['path'] ?? ''; 14 $path_arr = explode( '/', $path ); 15 $page_name = $path_arr[1] ?? ''; 16 17 // ページ名 ( $page_name ) に応じて $data を取得する 18 if( $page_name == 'products' ){ 19 $data = 'productページの場合の値'; 20 }elseif( $page_name == '' ){ 21 $data = 'フロントページの場合の値'; 22 } 23 24 return $data; // -> $data が見つからないエラーになる! 25}

###試したこと
エラーログで確認しましたら…、

php

1function getData(){ 2 3 // 値を確認 4 error_log( '$_SERVER["REQUEST_URI"]の値 -> ' . $_SERVER["REQUEST_URI"] ); 5 6 /*--- 以下略 ---*/ 7}

1回読んだだけで次の2つの出力があり、つまり REQUEST_URI が /undefined/ となる場合があるためだとわかりました

[12-Aug-2020 07:47:47 UTC] $_SERVER["REQUEST_URI"]の値 -> / [12-Aug-2020 07:47:47 UTC] $_SERVER["REQUEST_URI"]の値 -> /undefined/

これならば確かに、該当のソースコードの $page_name が /undefined/ となるわけですから、$data は見つかりません

そしてこのことはWordPressの仕様だと、別の質問で知りました(つまり /undefined/ を得てしまうことは避けられない)

###考えた対策
次の3つの対策を考えました

【対策1】条件分岐に /undefined/ を追加
上記コードの if に次のように追加する方法で、場当たり的に思います

php

1 2 // ページ名 ( $page_name ) に応じて $data を取得する 3 if( $page_name == 'products' ){ 4 $data = 'productページの場合の値'; 5 }elseif( $page_name == '' ){ 6 $data = 'フロントページの場合の値'; 7 } 8 9 // /undefined/ 用の if を追加 10 elseif( $page_name == '/undefined/' ){ 11 return; 12 } 13 14 return $data;

【対策2】初めに宣言
ifに一致しなくとも空文字を返す方法です

PHP

1 // 初めに空文字で宣言しておく 2 $data = ''; 3 4 // ページ名 ( $page_name ) に応じて $data を取得する 5 if( $page_name == 'products' ){ 6 $data = 'productページの場合の値'; 7 }elseif( $page_name == '' ){ 8 $data = 'フロントページの場合の値'; 9 } 10 11 return $data;

【対策3】定数を変更
undefined のときは空文字を定数にする方法で、個人的にはこの方がいいかと思っています

php

1define( 'URL', (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'] . ( $_SERVER['REQUEST_URI'] === '/undefined/' ? '' : $_SERVER['REQUEST_URI'] ) );

この3つしか対策が浮かびませんでしたが、【よりよい対策】もあれば教えて頂きたいです

WordPress入門者につきそもそも何か根本的に誤解していたりするかもしれませんので、お気づきのことがあれば遠慮なく仰ってください

アドバイスお待ちしてます!

追記

KazuhiroHatano様から【よりよい対策】として $_SERVER['REQUEST_URI'] でなく $GLOBALS['wp'] を試すようアドバイスを頂きました

さっそく「http://example.com/products/roomba/favorites/」の header.php にて以下試しました

productchild や userchild(わたしがリライトルールに加えたもの)が得られていますが、現在の $page_name がそのどちらかまではわかりません。また roombaや favorites の方は得らません。
なので冒頭の define のような情報は得られないのでは、と思いました。

PHP

1<div class="test"> 2<?php 3/* header.phpに記載 */ 4 5echo 'var_dump($GLOBALS["wp"]);を実行しました'.PHP_EOL; 6var_dump($GLOBALS['wp']); 7 8echo 'var_dump(home_url());を実行しました'.PHP_EOL; 9var_dump(home_url()); 10?> 11</div>

↓出力

PHP

1<div class="test"> 2var_dump($GLOBALS["wp"]);を実行しました 3object(WP)#411 (9) { 4 ["public_query_vars"]=> 5 array(51) { 6 [0]=> 7 string(1) "m" 8 [1]=> 9 string(1) "p" 10 [2]=> 11 string(5) "posts" 12 [3]=> 13 string(1) "w" 14 [4]=> 15 string(3) "cat" 16 [5]=> 17 string(12) "withcomments" 18 [6]=> 19 string(15) "withoutcomments" 20 [7]=> 21 string(1) "s" 22 [8]=> 23 string(6) "search" 24 [9]=> 25 string(5) "exact" 26 [10]=> 27 string(8) "sentence" 28 [11]=> 29 string(8) "calendar" 30 [12]=> 31 string(4) "page" 32 [13]=> 33 string(5) "paged" 34 [14]=> 35 string(4) "more" 36 [15]=> 37 string(2) "tb" 38 [16]=> 39 string(2) "pb" 40 [17]=> 41 string(6) "author" 42 [18]=> 43 string(5) "order" 44 [19]=> 45 string(7) "orderby" 46 [20]=> 47 string(4) "year" 48 [21]=> 49 string(8) "monthnum" 50 [22]=> 51 string(3) "day" 52 [23]=> 53 string(4) "hour" 54 [24]=> 55 string(6) "minute" 56 [25]=> 57 string(6) "second" 58 [26]=> 59 string(4) "name" 60 [27]=> 61 string(13) "category_name" 62 [28]=> 63 string(3) "tag" 64 [29]=> 65 string(4) "feed" 66 [30]=> 67 string(11) "author_name" 68 [31]=> 69 string(8) "pagename" 70 [32]=> 71 string(7) "page_id" 72 [33]=> 73 string(5) "error" 74 [34]=> 75 string(10) "attachment" 76 [35]=> 77 string(13) "attachment_id" 78 [36]=> 79 string(7) "subpost" 80 [37]=> 81 string(10) "subpost_id" 82 [38]=> 83 string(7) "preview" 84 [39]=> 85 string(6) "robots" 86 [40]=> 87 string(7) "favicon" 88 [41]=> 89 string(8) "taxonomy" 90 [42]=> 91 string(4) "term" 92 [43]=> 93 string(5) "cpage" 94 [44]=> 95 string(9) "post_type" 96 [45]=> 97 string(5) "embed" 98 [46]=> 99 string(11) "post_format" 100 [47]=> 101 string(10) "rest_route" 102 [48]=> 103 string(10) "productchild" 104 [49]=> 105 string(8) "username" 106 [50]=> 107 string(9) "userchild" 108 } 109 ["private_query_vars"]=> 110 array(26) { 111 [0]=> 112 string(6) "offset" 113 [1]=> 114 string(14) "posts_per_page" 115 [2]=> 116 string(22) "posts_per_archive_page" 117 [3]=> 118 string(9) "showposts" 119 [4]=> 120 string(8) "nopaging" 121 [5]=> 122 string(9) "post_type" 123 [6]=> 124 string(11) "post_status" 125 [7]=> 126 string(12) "category__in" 127 [8]=> 128 string(16) "category__not_in" 129 [9]=> 130 string(13) "category__and" 131 [10]=> 132 string(7) "tag__in" 133 [11]=> 134 string(11) "tag__not_in" 135 [12]=> 136 string(8) "tag__and" 137 [13]=> 138 string(12) "tag_slug__in" 139 [14]=> 140 string(13) "tag_slug__and" 141 [15]=> 142 string(6) "tag_id" 143 [16]=> 144 string(14) "post_mime_type" 145 [17]=> 146 string(4) "perm" 147 [18]=> 148 string(17) "comments_per_page" 149 [19]=> 150 string(8) "post__in" 151 [20]=> 152 string(12) "post__not_in" 153 [21]=> 154 string(11) "post_parent" 155 [22]=> 156 string(15) "post_parent__in" 157 [23]=> 158 string(19) "post_parent__not_in" 159 [24]=> 160 string(5) "title" 161 [25]=> 162 string(6) "fields" 163 } 164 ["extra_query_vars"]=> 165 array(0) { 166 } 167 ["query_vars"]=> 168 array(0) { 169 } 170 ["query_string"]=> 171 string(0) "" 172 ["request"]=> 173 NULL 174 ["matched_rule"]=> 175 NULL 176 ["matched_query"]=> 177 NULL 178 ["did_permalink"]=> 179 bool(false) 180} 181var_dump(home_url());を実行しました 182string(18) "http://example.com" 183</div> 184

追記2

KazuhiroHatano様へ
こちらは上記が「http://example.com」でも「http://example.com/products/roomba/favorites」でも出力されることを確認したコードになります

php

1<div class="test"> 2<?php 3/* header.phpに記載 */ 4 5// 上記の追記と同じものを$strに代入 6$str = 'object(WP)#411 (9) { 7/* 省略 */ 8}'; 9 10// 開いたページでの var_dump($GLOBALS['wp']) が $str と同じかどうかを確認 11ob_start(); 12var_dump($GLOBALS['wp']); 13$dump = rtrim(ob_get_contents()); 14ob_end_clean(); 15 16// $str が、var_dump($GLOBALS['wp']) であれば "$is_match is true" が echo される 17$is_match = ($str === $dump); 18echo '$is_match is ' . json_encode($is_match).PHP_EOL; 19 20// home_urlを確認 21var_dump(home_url()); // "string(18) "http://example.com" 22?> 23</div>

↓結果

http://example.com」 で実行しても 「http://example.com/products/roomba/favorites」 で実行してもこちらの結果でした

<div class="test"> $is_match is true string(18) "http://example.com </div>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/08/12 08:43

そもそも動的に変わる情報なので定数として運用するのは無理があるのでは?どうしてdefineなのでしょうか? $_SERVER自体はスーパーグローバル変数ですのでいつでもどこでもアクセスできます
ikemen

2020/08/12 08:49

コメントありがとうございます アクセスされたURLはいろいろな関数内で使いまわします そう使いまわすとき、関数と定数とグローバル関数しか方法を知らないのですが、何がいいでしょうか? 例えばあなたならアクセスされたURLをいろいろな関数内で使うときどうやりますか? 毎回 $_SERVER から呼びますか?
m.ts10806

2020/08/12 09:36

そもそもフルURLをずっと持っておかなければならない要件が思い当たりません。
guest

回答1

0

ベストアンサー

WordPressにおいて現在アクセスされているページの情報を得たいならば
$GLOBALS['wp']におおよそ充分な情報が格納されているはずです

投稿2020/08/12 10:00

KazuhiroHatano

総合スコア7804

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikemen

2020/08/12 10:31

WordPressマスター!ありがとうございます! 普通の固定ページとかなら取得できたのでしょうか… 今回のサイトは固定ページや投稿ページを使わず、ひたすらDBからJSONで取得するだけ(WordPress使い意味なしw)なので、質問の「$page_name」のような値は取得できないようでした やはり【対策3】が妥当ですかね
KazuhiroHatano

2020/08/12 11:11

global $wp はWordPressのルーティングのクラスのオブジェクトです つまるところURLリライトを通して得られたパラメータなどの解析結果が入ってます 一度 var_dump($GLOBALS['wp']); してみて中身を見てみてください
ikemen

2020/08/12 12:13

あ、はい、見てみましたが、たぶんなかったような… すみません今外なので後でまた見てみて、ここに結果を貼らせていただきます 夜分にありがとうございます
ikemen

2020/08/13 03:16

こんにちは!遅くなって申し訳ございませんが、var_dump($GLOBALS['wp']); の結果を質問に追記いたしました ここからは質問のdefineのような情報は得られないと見えたのですが、どう思われますでしょうか?
KazuhiroHatano

2020/08/13 06:15

$wpのmatched_ruleがnullっていうことは リライトルールの設定がうまくいってないんじゃないでしょうか add_rewrite_ruleのコードを追加した後で 管理画面でパーマリンク設定の更新はしましたか?
ikemen

2020/08/13 06:49

あ、いえ!していませんでした! 今しましたが matched_rule は null で、特に変化なかったです 普通にPJAXで遷移できるし自作SELECTで情報も取れていますが、どうしたんでしょうね
KazuhiroHatano

2020/08/14 02:17

よくみたらrequestの値も空ですね 追記されたのは/products/roomba/favorites/の$wpってことですが これはフロントページのものではないでしょうか $wpのrequestにはhome_url()以降のURIが入っているはずですし おおよそ追加されたリライトルールにマッチしなければ 固定ページであると推定してルーティングするようになっているはずなので フロント以外ではmatched_ruleがnullなんてことにならないはず どういう経路でこのプログラムは実行されているのでしょう
KazuhiroHatano

2020/08/14 02:18

というか、もしかして/products/roomba/favorites/が WordPressのフロントページなんですか?
ikemen

2020/08/14 05:08 編集

サイト的にはフロントページは「http://example.com」ですが、フロントページという概念が微妙かもしれません WordPressにおいてフロントページがどのように定義されているのかわかりませんが、今回テンプレートの中身は以下になっていて、HTMLは受け取ったJSONをもとにJSで組み立てています index.php, page.php. single.php などすべて、以下3行だけです(front-page.phpやカスタムテンプレートは使っていません) ----------------- <?php get_header(); get_footer(); ----------------- これは「どのテンプレートも一緒(フロントページを定義しているテンプレートがない)」ということになっていて、だからすべてのページがフロントページのように扱われる、といった状況になっているとかでしょうか?
KazuhiroHatano

2020/08/14 05:13

home_url()の値はどのようになっているでしょうか?
KazuhiroHatano

2020/08/14 06:01

では追記の$wpの内容は /products/roomba/favorites/でアクセスされた際の $wpの内容ではないはずです
ikemen

2020/08/14 14:14

こんばんは、確認遅れてすみません やはり間違いなかったです 追記2がその確認で、ご覧のように目視でなくコードを使って確認しました
KazuhiroHatano

2020/08/15 18:04

/products/roomba/favoritesでアクセスされた際に global $wpのmatched_ruleがnullなのに 正常にアクセス・表示できてるなんてはずがないんです なぜならこのglobal $wpこそががWordPressにおいて クエリとテンプレートを決定しているからです どういう経路でこのプログラムは実行されているのでしょうか? ajaxとかでしょうか?
ikemen

2020/08/16 03:34

ページ遷移の際はすべてajaxですが、今回追記した結果はいずれもURL直打ちで最初にアクセスしたときの話です でも、こないだ言ったとおりWP_Queryなどは使わず自作SELECTですし、テンプレートもこないだの3行だけなので、そういうときは global $wp の重要な値が null でも問題ないということになっているのかもですね
KazuhiroHatano

2020/08/19 01:41

勝手な憶測ですが、 フロントページはajaxにおけるテンプレート的なページになっていて 何らかの形でWordPressにはすべてのアクセスをフロントページとして扱うようにして アクセスされたURLによってテンプレートに違いが出ないようにしているんじゃないでしょうか それをどのような手段で実現しているのかは不明ですが WPですべてのアクセスをフロントページへの アクセスとして扱う(+リダイレクト阻止)なら add_filter('redirect_canonical','__return_false'); add_filter('do_parse_request','__return_false'); で事足ります この方法でやっていれば$_SERVER['REQUEST_URI']が消えてることもないはずです $_SERVER['REQUEST_URI']を上書きして 実現するようなことをしているとかならやり方が乱暴です
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問