実現したいこと
WordPressでキャッシュ機能を使う際にセッション関数は推奨されていないため別の選択肢で添付ファイルを保存したい
発生している問題・分からないこと
ファイルアップロードが可能な掲示板を作成しているのですが、コードを書いた後に $_SESSION が WordPress で非推奨だと知りどのように修正すべきか悩んでおります。
該当のソースコード
functions.php
1<?php 2function Chk_ngword($str, $mes, &$error) 3{ 4 // NGワードリスト配列の定義 5 $ng_words = ['死ね', 'アホ', '殺す', 'バカ']; 6 foreach ($ng_words as $ngWordsVal) { 7 // 対象文字列にキーワードが含まれるか 8 if (false !== mb_strpos($str, $ngWordsVal)) { 9 $error[] = $mes; 10 } 11 } 12} 13/* $str = 名前、タイトル、質問文 */ 14function Chk_StrMode($str) 15{ 16 // タグを除去 17 $str = strip_tags($str); 18 // 連続する空白をひとつにする 19 $str = preg_replace('/[\x20\xC2\xA0]++/u', "\x20", $str); 20 // 連続する改行をひとつにする 21 $str = preg_replace("/(\x20*[\r\n]\x20*)++/", "\n", $str); 22 // 前後の空白を除去 23 $str = mb_ereg_replace('^( ){0,}', '', $str); 24 $str = mb_ereg_replace('( ){0,}$', '', $str); 25 $str = trim($str); 26 // 特殊文字を HTML エンティティに変換する 27 $str = htmlspecialchars($str); 28 29 return $str; 30} 31/* 未入力チェックファンクション */ 32function Chk_InputMode($str, $mes, &$error) 33{ 34 if ('' == $str) { 35 $error[] = $mes; 36 } 37} 38 39/* 以下追加 */ 40function CheckUrl($checkurl, $mes, &$error) 41{ 42 if (preg_match("/[\.,:;]/u", $checkurl)) { 43 $error[] = $mes; 44 } 45} 46 47function bbs_answer_confirm() 48{ 49 // 統一ユーザーIDを取得 50 $user_id = $_COOKIE['user_id'] ?? null; 51 52 if (!$user_id) { 53 wp_send_json_error(['message' => 'ユーザーIDが見つかりません']); 54 exit; 55 } 56 57 // トランジェントからデータ取得 58 $transient_key = 'bbs_answer_' . $user_id; 59 $answer_data = get_transient($transient_key); 60 61 if (!$answer_data) { 62 wp_send_json_error(['message' => '投稿データが見つかりません']); 63 exit; 64 } 65 66 // データベースへの保存処理 67 global $wpdb; 68 69 // 親質問のIDを取得 70 $unique_id = $answer_data['unique_id']; 71 $sql = "SELECT * FROM {$wpdb->prefix}sortable WHERE unique_id = %s"; 72 $query = $wpdb->prepare($sql, $unique_id); 73 $rows = $wpdb->get_results($query); 74 75 if (empty($rows)) { 76 wp_send_json_error(['message' => '親質問が見つかりません']); 77 exit; 78 } 79 80 $parent_id = $rows[0]->id; 81 82 // 回答をデータベースに挿入 83 $sql = "INSERT INTO {$wpdb->prefix}sortable(parent_id, text, name, ip, user_id) VALUES(%d, %s, %s, %s, %s)"; 84 $query = $wpdb->prepare( 85 $sql, 86 $parent_id, 87 $answer_data['text'], 88 $answer_data['name'], 89 $_SERVER['REMOTE_ADDR'], 90 $user_id // 投稿者のユーザーIDも保存 91 ); 92 93 $query_result = $wpdb->query($query); 94 95 if ($query_result === false) { 96 wp_send_json_error(['message' => '投稿に失敗しました: ' . $wpdb->last_error]); 97 exit; 98 } 99 100 $new_post_id = $wpdb->insert_id; 101 102 // 添付ファイルの処理 103 if (!empty($answer_data['attach'])) { 104 $upload_dir = wp_upload_dir(); 105 $filenames = []; 106 107 // 新しい投稿のunique_idを取得 108 $sql = "SELECT unique_id FROM {$wpdb->prefix}sortable WHERE id = %d"; 109 $query = $wpdb->prepare($sql, $new_post_id); 110 $new_unique_id = $wpdb->get_var($query); 111 112 foreach ($answer_data['attach'] as $i => $file_data) { 113 $type = explode('/', $file_data['type']); 114 $ext = $type[1] ?? 'tmp'; 115 116 if ($i == 3) { 117 $n = 'usericon'; 118 } else { 119 $n = $i + 1; 120 } 121 122 $filename = "{$new_unique_id}_{$n}.{$ext}"; 123 $filenames[$i] = $filename; 124 $attach_path = $upload_dir['basedir'] . '/attach/' . $filename; 125 126 file_put_contents($attach_path, $file_data['data']); 127 } 128 129 // ファイル名をデータベースに更新 130 $sql = "UPDATE {$wpdb->prefix}sortable SET attach1=%s, attach2=%s, attach3=%s, usericon=%s WHERE id=%d"; 131 $query = $wpdb->prepare( 132 $sql, 133 $filenames[0] ?? '', 134 $filenames[1] ?? '', 135 $filenames[2] ?? '', 136 $filenames[3] ?? '', 137 $new_post_id 138 ); 139 $wpdb->query($query); 140 } 141 142 // 成功時はトランジェントを削除 143 delete_transient($transient_key); 144 145 wp_send_json_success(['message' => '回答が投稿されました']); 146 exit; 147} 148add_action('wp_ajax_bbs_answer_confirm', 'bbs_answer_confirm'); 149add_action('wp_ajax_nopriv_bbs_answer_confirm', 'bbs_answer_confirm'); 150?>
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
AIに聞いたところトランジェントを使用した方法を教えてくれた為そちらを実装してみたのですが、ファイルがアップロードされた場合の $answer_data['attach'] にバイナリ(file_get_contents)の大きなデータが含まれており失敗しているようです。
※ 回答画面(表示する側のコード)
https://wandbox.org/permlink/zAmoPPYI2iKh4JjD
###functions.php(AIに聞いて修正後のコード)
/* 回答タイトルとスタンプ画像なし(回答掲示板) */ function bbs_answer_confirm() { // 統一ユーザーIDを取得 $user_id = $_COOKIE['user_id'] ?? null; if (!$user_id) { wp_send_json(['error' => 'ユーザーIDが見つかりません']); exit; } // トランジェントからデータ取得 $transient_key = 'bbs_answer_' . $user_id; $answer_data = get_transient($transient_key); if (!$answer_data) { wp_send_json(['error' => '投稿データが見つかりません']); exit; } // データベースへの保存処理 global $wpdb; // 親質問のIDを取得 $unique_id = $answer_data['unique_id']; $sql = "SELECT * FROM {$wpdb->prefix}sortable WHERE unique_id = %s"; $query = $wpdb->prepare($sql, $unique_id); $rows = $wpdb->get_results($query); if (empty($rows)) { wp_send_json(['error' => '親質問が見つかりません']); exit; } $parent_id = $rows[0]->id; // 回答をデータベースに挿入 $sql = "INSERT INTO {$wpdb->prefix}sortable(parent_id, text, name, ip, user_id) VALUES(%d, %s, %s, %s, %s)"; $query = $wpdb->prepare( $sql, $parent_id, $answer_data['text'], $answer_data['name'], $_SERVER['REMOTE_ADDR'], $user_id // 投稿者のユーザーIDも保存 ); $query_result = $wpdb->query($query); if ($query_result === false) { wp_send_json(['error' => '投稿に失敗しました: ' . $wpdb->last_error]); exit; } $new_post_id = $wpdb->insert_id; // 添付ファイルの処理 if (!empty($answer_data['attach'])) { $upload_dir = wp_upload_dir(); $filenames = []; // 新しい投稿のunique_idを取得 $sql = "SELECT unique_id FROM {$wpdb->prefix}sortable WHERE id = %d"; $query = $wpdb->prepare($sql, $new_post_id); $new_unique_id = $wpdb->get_var($query); foreach ($answer_data['attach'] as $i => $file_data) { $type = explode('/', $file_data['type']); $ext = $type[1] ?? 'tmp'; if ($i == 3) { $n = 'usericon'; } else { $n = $i + 1; } $filename = "{$new_unique_id}_{$n}.{$ext}"; $filenames[$i] = $filename; $attach_path = $upload_dir['basedir'] . '/attach/' . $filename; file_put_contents($attach_path, $file_data['data']); } // ファイル名をデータベースに更新 $sql = "UPDATE {$wpdb->prefix}sortable SET attach1=%s, attach2=%s, attach3=%s, usericon=%s WHERE id=%d"; $query = $wpdb->prepare( $sql, $filenames[0] ?? '', $filenames[1] ?? '', $filenames[2] ?? '', $filenames[3] ?? '', $new_post_id ); $wpdb->query($query); } // 成功時はトランジェントを削除 delete_transient($transient_key); wp_send_json(['error' => '']); exit; }
補足
