質問するログイン新規登録
WordPress

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

PHP

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

セッション

Sessionはクライアントがサーバに送ったすべてのリクエストのことを指します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

3回答

813閲覧

ファイルアップロード機能をセッション関数を使わずに実装することは可能でしょうか?

homepage-site

総合スコア71

WordPress

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

PHP

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

セッション

Sessionはクライアントがサーバに送ったすべてのリクエストのことを指します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2025/07/07 04:44

0

0

実現したいこと

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; }

補足

※参考サイト
https://blog.8bit.co.jp/?p=22400

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

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

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

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

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

homepage-site

2025/07/11 03:49

Lhankor_Mhy さん申し訳ありません。 どうしても答えが知りたくマルチポストしてしまいました。
homepage-site

2025/07/11 04:22

miyabi-sun さん先にテラテイルで質問をしたのでもう少し待つべきでした申し訳ありません。
Lhankor_Mhy

2025/07/11 09:32

homepage-siteさん、すみません、言葉が足りませんでしたね。失礼しました。 miyabi-sunさん、補足ありがとうございます。
guest

回答3

0

とりあえず、無意味にトランジェントにバイナリデータをブチこむ荒技から改め、テンポラリファイルとして受けてからアップロード用ディレクトリに移動してDB上の投稿データにアップロード用ディレクトリに保存したファイルのパスを保存する方向に設計を方針転換するようでよかったです。

で、今回の質問に至った前段階として気になったのですが、WordPress上でのファイルアップロードに対応した掲示板機能を求めて、なぜ導入が容易かつセキュリティ面での配慮が楽な既存のプラグイン類を利用しないのでしょうか?
例:WordPressでの掲示板の設置方法を徹底解説!おすすめのプラグインも紹介

もちろんWordPressの仕組みとセキュリティ対策の勉強目的であれば特に問題ないのですが、今のご時世webサイト特に著名なWordPressで構築されたサイトは個人ブログサイトであっても常時セキュリティ侵害を目的とした多数のアクセスにさらされる時代です。テキスト投稿やファイルのアップロードというサーバ上のデータやファイルをネットから更新する機能はWordPress/PHP/サーバ設定のセキュリティ対応を理解したうえで組まないと、プログラムの実装不備を突かれてサイトやサーバの乗っ取りなどで自分でだけでなく一般訪問ユーザーにも被害を与える事態を招く恐れがあります。
セキュアなwebサイト向けプログラミングができる知見があるのならいいですが、基本的な方針や設計を間違えた回答する恐れを内包する生成AI利用任せなのを踏まえると、まずWordPressの既存資産(テーマやプラグイン)を導入できないかを検討したほうがよいと思いますし、個人的にはセキュアなプログラミングに不慣れな段階ではネットからのデータをDBやファイルに取り込む公開中サイト機能の自作はお奨めしません。

上記のように自作に至る流れなどが気になったので指摘させていただきました。

投稿2025/07/15 00:36

AnMoreNight

総合スコア115

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

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

homepage-site

2025/07/16 07:48

AnMoreNight さん回答ありがとうございます。 プラグインを利用しなかった点になるのですが、マイページを活用したログイン制の掲示板を作成したかったという理由になります。 セキュリティのリスクはありますがグーグルでのログインシステムを第一選択肢にして進めることで個人情報漏洩につながるリスクは減ると考えております。
guest

0

この質問のメインテーマは画像のアップロードとブラウザ上でのキャッシュだと思いますが、それぞれ別物なんじゃないかと思います。

まず、画像のアップロードというのは超一般的な要件ですから、画像アップロードができる機能をまずは開発してみてそれが動作することを確認してから、つけたい機能をつけないとトラブルシューティングで困るのは火を見るよりも明らかだと思います。

また、ブラウザ上での画像のキャッシュだと思いますが、セッションとの関連性がおそらくないのでもう少し用語整理をした方がよいかもしれません。

質問の方法に関して指摘したいのですが、まずソースコードが人に見せるようのものとは到底思えないのと、普通の感性であれば必要な部分だけを切り取って、何を見てほしいのかをはっきりさせるのではないだろうかと思います。
もし、WordPress界隈でこの方法がセオリーであれば大きなお世話かもしれませんが。

$_SESSION が WordPress で非推奨という点について少し怪しかったので以下のワードで検索してみました。
wordpress $_SESSION 非推奨

Topに非推奨という情報が1件だけで出てきはしたのですが、その他についてはあなたが様々なサイトでマルチポストしていることが分かっただけでした。。。

投稿2025/07/11 16:29

u2025

総合スコア42

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

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

homepage-site

2025/07/14 04:05

u2025 さんアドバイスありがとうございます。 $_SESSION が WordPress で非推奨ということで一気に複数のコードを変更しようとしておりました申し訳ありません。 画像アップロードに関するコードを一時ファイルディレクトリ(例:wp-content/uploads/tmp)に保存する方法で修正してみます。 複数の機能に関するコードを同じ質問で解決したいと欲張ってしまい不必要な部分まで載せておりました以後気を付けます。 $_SESSION が WordPress で非推奨という点について AI にソース元の webサイトを聞いたところ核心的な情報には辿り着けませんでした。 検索した際に出てきた情報をまとめてみました。 ①サーバー側からのなんらかの送信が行われる前に「template_redirect」アクションフックで実行する ②既に実行済みの場合の多重実行(セッションを新規に張る)はしない ③プラグインまたはテーマ内でsession_start()関数を使用したときに、設定 read_and_close オプションを指定する。 これを true にすると、セッションを読み込んだらその場ですぐにクローズします。 ※ 参考サイト https://www.php.net/manual/ja/function.session-start.php ※ 参考サイト 1.StackExchange(Site Health警告「A PHP session was detected...」):“Wordpress doesn't use Sessions by design… The session should be closed by session_write_close() before making any HTTP requests.” https://wordpress.stackexchange.com/questions/377483/site-health-an-active-php-session-was-detected?utm_source=chatgpt.com 2.Pantheonドキュメント:“WordPress Core does not use sessions… the WordPress community largely discourages plugin authors from using PHP sessions.” https://docs.pantheon.io/guides/php/wordpress-sessions?utm_source=chatgpt.com ※ chatgpt のアドバイス これらの公式な見解から、セッションの利用はREST・キャッシュ・スケーラビリティなどの観点で重大な副作用を引き起こす可能性が高いため、推奨されていません。代替としてはトランジェントやクッキー、独自のDBストレージを検討すべきです。 ※ 検索した際に出てきた情報 1.https://wp-doctor.jp/blog/2021/01/06/ワードプレス%E3%80%80サイトヘルス-で「アクティブな-php/ 2.https://www.scitech.co.jp/use-session-in-wordpress 3.https://ja.thewordcracker.com/基本/워드프레스-サイトの健康アクティブPHPセッションを検出しました/
guest

0

ベストアンサー

ファイルのアップロードにセッションは不要です、単にpostするだけで済みます。
ただしアップロード後データを確認させて確定したい場合は一時的にセッションなどに保持する必要があります。
どうしても確認後確定をしたい場合はブラウザ側でformdataにデータを保持しておいて確定時点で再送するなど特殊な処理が必要になるでしょう

投稿2025/07/09 03:08

yambejp

総合スコア117973

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

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

homepage-site

2025/07/11 03:54 編集

yambejpさん回答ありがとうございます。 トランジェントを使用した方法ではエラーが出るため一時ディレクトリに保存してパスだけを transient に記録する方式に変更してみたのですが、ブラウザ側でformdataにデータを保持する方法もあるんですね検討してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問