前提・実現したいこと
WordPressで独自テーブルwp_colors
のデータを出力しています。
このときデータがなければ404でいいのですが、データがあるときは404を回避したいです。
発生している問題・エラーメッセージ
404を回避できず、コンソール画面にこのエラーメッセージが表示されてしまいます。
GET https://example.com/red/ 404
該当のソースコード
こんな風にwp_colors
テーブルを作り、値をinsert
しておきます。
SQL
1create table wp_colors ( 2 ID int(10), 3 color varchar(100), 4 details varchar(1000) 5); 6 7insert into wp_colors 8values (1, 'red', '情熱の色'); -- 実際のレコードは10万行ほどあります
そして "https://example.com/red" にアクセスしたときに以下のPHPでred
のレコードを取得し、JSでHTMLを描画します。
php
1/* 2functions.php 3*/ 4 5// wp_localize_script でレコードを出力 6add_action( 'wp_enqueue_scripts', 'enqueue_data' ); 7function enqueue_data(){ 8 9 // レコードを取得 10 $color = 'red'; 11 $colors = get_colors( $color ); 12 13 // visit.jsへ出力 14 $colors = json_encode( $colors ); // $colors = [ {"details": "情熱の色"} ] 15 wp_localize_script( 'visit.js', 'colors', $colors ); 16} 17 18// レコードを取得 19function get_colors( $color ){ 20 $query = "select details from wp_colors where color = '{$color}';"; 21 return $wpdb->get_results( $query, ARRAY_A ); 22}
JavaScript
1/* 2visit.js 3*/ 4 5console.log(colors); // wp_localize_script から値を受け取れていることを確認 6colors.forEach((color)=>{ 7 $('body').append(`<p>${color.details}<p>`); // HTMLを描画 8});
この結果、HTMLは<p>情熱の色<p>
と描画できますが、しかしこのページは404ステータスになってしまいます。
どのようにすれば普通のwp_posts
等と同じように、「データがあるので404ではないですよ」とステータスを返すことができるでしょうか?
試したこと
以下add_rewrite_rule
を用いて、"https://example.com/red" にアクセスしたときに無理矢理post=1
(つまりWordPressインストール時にあるHello,World!の記事)に飛ばしましたところ、404は回避できました。
PHP
1/* 2functions.php 3*/ 4 5// 404を回避 6add_action('init', 'rewrite_404_v1'); 7function rewrite_404_v1() { 8 // リライトを実行 → こうすると404は回避できる 9 $regex = 'red'; 10 add_rewrite_rule($regex, 'index.php?post=1', 'top'); 11}
あとはこれを現在URLに応じて動的に指定するだけだと思い次のように修正したところ、また404になってしまいました。つまりどうやら、現在URLに応じて動的に指定する、ということがadd_rewrite_rule
ではできない様子なのです。
PHP
1/* 2functions.php 3*/ 4 5// 現在URLを定義 6define( 'URL', (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'] . ( $_SERVER['REQUEST_URI'] === '/undefined/' ? '' : $_SERVER['REQUEST_URI'] ) ); 7 8// 404を回避 9add_action('init', 'rewrite_404_v2'); 10function rewrite_404_v2() { 11 12 // 現在URLからcolorを取得 13 $paths = explode( '/', parse_url(URL)['path'] ); 14 $color = urldecode( $paths[1] ); // $color = 'red' や 'blue' など 15 16 // レコードを取得 17 $colors = get_colors( $color ); 18 if ( empty($colors) ) { 19 20 // レコードがない場合は 404 なので何もしない 21 22 } else { 23 24 // リライトを実行 → こうすると効かない! 25 $regex = $color; 26 add_rewrite_rule($regex, 'index.php?post=1', 'top'); 27 28 } 29}
続いて、URL構造を "https://example.com/red" でなく "https://example.com/color/red" にした場合として下記rewrite_404_v3
を試しましたが、こちらも上記rewrite_404_v2
同様にできませんでした。
PHP
1/* 2functions.php 3*/ 4 5// 現在URLを定義 6define( 'URL', (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'] . ( $_SERVER['REQUEST_URI'] === '/undefined/' ? '' : $_SERVER['REQUEST_URI'] ) ); 7 8// 404を回避 9add_action('init', 'rewrite_404_v3'); 10function rewrite_404_v3() { 11 12 // 現在URLからcolorを取得 13 $paths = explode( '/', parse_url(URL)['path'] ); 14 $color = urldecode( $paths[2] ); // $color = 'red' や 'blue' など 15 16 // レコードを取得 17 $colors = get_colors( $color ); 18 if ( empty($colors) ) { 19 20 // レコードがない場合は 404 なので何もしない 21 22 } else { 23 24 // リライトを実行 → これもやはり効きませんでした 25 $regex = 'colors/(\w+)/?'; // ご回答の '/colors/(\w+)/?' と、左記の 'colors/(\w+)/?' で試しました 26 add_rewrite_rule($regex, 'index.php?post=1', 'top'); 27 28 } 29}
補足
一.wp_colors
の使用は絶対でして、wp_tags
などデフォルトのテーブルは使わないものとします。
二.すべてのソースコードは簡易版であり、実際はインジェクション対策などを介していますのでご安心ください。
三.HTMLをPHPで描画することは一切なく、該当のソースコードの流れのようにwp_localize_script
で出力された後にJSで描画されるか、もしくはページ遷移の際はajaxでechoされた後にJSで描画されます。そのため index.php、single.php、page.php は全て以下の3行だけです。(なのでWordPressを使う必要性はあまりないわけですが…)
PHP
1<?php 2get_header(); 3get_footer();
四.もちろん「パーマリンク設定 > 変更を保存」は実行済みです。
五.add_rewrite_rule
にこだわりはないので、他の方法でも全く構いません。
六.add_rewrite_rule
の直後にflush_rewrite_rules
を実行したら解決しましたが、高コストらしいので避けたい操作です。
以上です。
魔改造で申し訳ございませんが、宜しくお願い致します。

回答1件
あなたの回答
tips
プレビュー