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

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

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

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

Q&A

解決済

3回答

1747閲覧

phpでフォロー機能実行時、セッションが切れてしまう

ryouya

総合スコア14

PHP

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

0グッド

0クリップ

投稿2020/09/15 09:18

お世話になっております。
下記の問題について知見のある方がいらっしゃいましたらご教示お願いいたします。

#起こっている問題
PHPにてフォロー機能を実装しているのですが、
フォローボタンを押すとセッションが切れてしまいます。
イメージ説明
↓フォローボタンクリック
イメージ説明

下記のコードでajax処理をしているのですが、どこかでセッションを切ってしまっているのでしょうか。
ご確認お願いいたします。

php

1<script src=" https://code.jquery.com/jquery-3.4.1.min.js "></script> 2<script src="../js/user_page.js"></script> 3<?php 4session_start(); 5session_regenerate_id(true); 6require_once('config.php'); 7//require_once('auth.php'); 8 9function _debug( $data, $clear_log = false ) { 10 $uri_debug_file = $_SERVER['DOCUMENT_ROOT'] . '/debug.txt'; 11 if( $clear_log ){ 12 file_put_contents($uri_debug_file, print_r($data, true)); 13 } 14 file_put_contents($uri_debug_file, print_r($data,true), FILE_APPEND); 15 } 16 17 18if(isset($_POST)){ 19 20 21 $follow_id = $_POST['follow_id']; 22 $followed_id = $_POST['followed_id'] ?? $follow_id; 23 24 // すでに登録されているか確認して登録、削除のSQL切り替え 25 if(check_follow($_SESSION['staff_code'],$follow_id)){ 26 $action = '解除'; 27 $flash_type = 'error'; 28 $sql ="DELETE 29 FROM relation 30 WHERE :follow_id = follow_id AND :follower_id = follower_id"; 31 }else{ 32 $action = '登録'; 33 $flash_type = 'sucsess'; 34 $sql ="INSERT INTO relation(follow_id,follower_id) 35 VALUES(:follow_id,:follower_id)"; 36 } 37 try { 38 $dsn='mysql:dbname=shop;host=localhost;charset=utf8'; 39 $user='root'; 40 $password=''; 41 $dbh=new PDO($dsn,$user,$password); 42 $stmt = $dbh->prepare($sql); 43 $stmt->execute(array(':follow_id' => $followed_id , ':follower_id' => $follow_id)); 44 45 } 46 47 catch (\Exception $e) { 48 error_log('エラー発生:' . $e->getMessage()); 49 set_flash('error',ERR_MSG1); 50 echo json_encode("error"); 51 52 } 53 }

#関連ファイル
フォローボタンがあるユーザーページ

//staff_disp.php <?php session_start(); session_regenerate_id(true); ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ろくまる農園</title> <script src=" https://code.jquery.com/jquery-3.4.1.min.js "></script> <script src="../js/user_page.js"></script> </head> <body> <?php require_once('../function.php'); $current_user = $_SESSION['staff_code']; var_dump($current_user); try { $staff_code=$_GET['staffcode']; $dsn = 'mysql:dbname=shop;host=localhost;charset=utf8'; $user='root'; $password=''; $dbh=new PDO($dsn,$user,$password); $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); $sql='SELECT name FROM mst_staff WHERE code=?'; $stmt=$dbh->prepare($sql); $data[]=$staff_code; $stmt->execute($data); $rec = $stmt -> fetch(PDO::FETCH_ASSOC); $staff_name = $rec['name']; $dbh = null; } catch(Exception $e) { print'ただいま障害により大変ご迷惑をおかけしております。'; exit(); } function check_follow($follow_user,$follower_user){ $dsn='mysql:dbname=shop;host=localhost;charset=utf8'; $user='root'; $password=''; $dbh=new PDO($dsn,$user,$password); $sql = "SELECT follow_id,follower_id FROM relation WHERE :follow_id =follow_id AND :follower_id = follower_id"; $stmt = $dbh->prepare($sql); $stmt->execute(array(':follow_id' => $follow_user, ':follower_id' => $follower_user)); return $stmt->fetch(); } ?> スタッフ情報参照<br /> <br /> スタッフコード<br /> <?php print $staff_code; ?> <br /> <br /> スタッフ名<br /> <?php print $staff_name;?> <?php var_dump($_SESSION['staff_code']);?> <br /> <br /> <form action="#" method="post"> <input type="hidden" class="profile_user_id"> <input type="hidden" name="follow_user_id" value="<?= $_SESSION['staff_code'] ?>"> <!-- フォロー中か確認してボタンを変える --> <button class="follow_btn"> <?php if (check_follow($_SESSION['staff_code'],$staff_code)): ?> フォロー中 <?php else: ?> フォロー <?php endif; ?> </button> </form> <form> <input type="button" onclick="history.back()"value="戻る"> </form> </body> </html>

ajax処理を行うためのjsファイル

//user_page.js function get_param(name, url) { if (!url) url = window.location.href; //window.location.hrefは現在のURLを取得 name = name.replace(/[[]]/g, "\$&"); //replaceは文字の置換を行う //`//g`は//の中の文字をすべて第二引数の文字に変換する // []はその中の文字があるかを判断 var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), //RegExpは引数の値があったときにtureを返す results = regex.exec(url); //regexp.exec(url)でregexとurlがマッチしている値をresultsに返しています if (!results) return null; if (!results[2]) return false; return decodeURIComponent(results[2].replace(/+/g, " ")); } $(document).on('click','.favorite_btn',function(e){ e.stopPropagation(); var $this = $(this), page_id = get_param('page_id'), post_id = get_param('procode'); //prev()は$thisの直前にあるhtml要素を取得する //val()は取得したいhtml要素のvalue値を取得する //page_idはユーザーのID $.ajax({ type: 'POST', url: '../ajax_post_favorite_process.php', dataType: 'json', data: { page_id: page_id, post_id: post_id} }).done(function(data){ // php側でエラーが発生したらリロードしてエラーメッセージを表示させる if(data ==="error"){ location.reload(); }else{ // アイコンを切り替える } }).fail(function() { location.reload(); }); }); $(document).on('click','.follow_btn',function(e){ e.stopPropagation(); var $this = $(this), followed_id = get_param('staffcode'), follow_id = $this.prev().val(); //prev()は指定した$thisの直前にあるHTML要素を取得する $.ajax({ type: 'POST', url: '../ajax_follow_process.php', dataType: 'json', data: { followed_id: followed_id, follow_id: follow_id} }).done(function(data){ // php側の処理に合わせてボタンを更新する // php側でエラーが発生したらリロードしてエラーメッセージを表示させる if(data === "error"){ location.reload(); }else if(data['action'] ==="登録"){ $this.toggleClass('following') $this.text('フォロー中'); }else if(data['action'] ==="解除"){ $this.removeClass('following'); $this.removeClass('unfollow') $this.text('フォロー'); } // プロフィール内のカウントを更新する $follow_count.text(data['follow_count']); $follower_count.text(data['follower_count']); }).fail(function() { location.reload(); }); });

ajax処理を行うためのphpファイル

//ajax_follow_process.php <script src=" https://code.jquery.com/jquery-3.4.1.min.js "></script> <script src="../js/user_page.js"></script> <?php session_start(); session_regenerate_id(true); require_once('config.php'); //require_once('auth.php'); if(isset($_POST)){ $follow_id = $_POST['follow_id']; $followed_id = $_POST['followed_id'] ?? $follow_id; // すでに登録されているか確認して登録、削除のSQL切り替え if(check_follow($_SESSION['staff_code'],$follow_id)){ $action = '解除'; $flash_type = 'error'; $sql ="DELETE FROM relation WHERE :follow_id = follow_id AND :follower_id = follower_id"; }else{ $action = '登録'; $flash_type = 'sucsess'; $sql ="INSERT INTO relation(follow_id,follower_id) VALUES(:follow_id,:follower_id)"; } try { $dsn='mysql:dbname=shop;host=localhost;charset=utf8'; $user='root'; $password=''; $dbh=new PDO($dsn,$user,$password); $stmt = $dbh->prepare($sql); $stmt->execute(array(':follow_id' => $followed_id , ':follower_id' => $follow_id)); } catch (\Exception $e) { error_log('エラー発生:' . $e->getMessage()); set_flash('error',ERR_MSG1); echo json_encode("error"); } }

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

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

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

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

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

guest

回答3

0

自己解決

自己解決しました。

ユーザー情報をセッションで取得せず、
パスから取得するようにしたところ正常に動きました。

投稿2020/10/03 06:05

ryouya

総合スコア14

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

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

0

下記サイトを参照して解決できました。(と思います)
SESSION情報を維持したままAjaxな処理を行う方法

以下は動作を確認した超シンプルなソースです。

HTML

1<html> 2 <head> 3 <title>AjaxSample</title> 4 5 <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> 6 <script> 7 $(document).on('click', '#btnSave', function() { 8 $.ajax({ 9 type: 'POST', 10 url: './write-session.php', 11 data: { 12 'id': document.getElementById('txtSave').value 13 } 14 // 追加 START 15 }).beforeSend(function(xhr) { 16 xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content')); 17 // 追加 END 18 }).fail(function() { 19 alert('fail'); 20 }); 21 }); 22 $(document).on('click', '#btnLoad', function() { 23 $.ajax({ 24 type: 'GET', 25 url: './read-session.php', 26 }).done(function(data) { 27 document.getElementById('txtLoad').value = data; 28 }).fail(function() { 29 alert('fail'); 30 }); 31 }); 32 </script> 33 </head> 34 <body> 35 <form action="#" method="POST"> 36 <table> 37 <tr> 38 <th>Input</th> 39 <td> 40 <input id="txtSave" type="text"> 41 </td> 42 <td> 43 <input id="btnSave" name="btnSave" type="button" value="Save"> 44 </td> 45 </tr> 46 <tr> 47 <th>Output</th> 48 <td> 49 <input id="txtLoad" type="text"> 50 </td> 51 <td> 52 <input id="btnLoad" name="btnLoad" type="button" value="Load"> 53 </td> 54 </tr> 55 </table> 56 </form> 57 </body> 58</html>

PHP

1<?php 2 session_start(); 3 $_SESSION['id'] = $_POST['id']; 4?>

PHP

1<?php 2 session_start(); 3 echo($_SESSION['id']); 4?>

投稿2020/09/17 00:21

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

ryouya

2020/09/17 10:47

回答ありがとうございます! また、実装し確認してくださりありがとうございますm(__)m 指摘事項のコードを追記したのですが、セッションが切れてしまいました。。 追記する箇所が間違っていますでしょうか?? ''' $.ajax({ type: 'POST', url: '../ajax_follow_process.php', dataType: 'json', data: { followed_id: followed_id, follow_id: follow_id} }).beforeSend(function(xhr) { //追記 xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content')); //追記 }) .done(function(data){  if(data === "error"){ location.reload(); }else if(data['action'] ==="登録"){ $this.toggleClass('following') $this.text('フォロー中'); }else if(data['action'] ==="解除"){ $this.removeClass('following'); $this.removeClass('unfollow') $this.text('フォロー'); } // プロフィール内のカウントを更新する $follow_count.text(data['follow_count']); $follower_count.text(data['follower_count']); }).fail(function() { location.reload(); }); }); '''
退会済みユーザー

退会済みユーザー

2020/09/17 12:03

すみません、根本的に勘違いしてたかもです。 「Undefined index: staff_code」は「$_SESSIONに'staff_code'ってキーが存在しないよ」って意味です。 ソースを見直しましたが、確かに$_SESSION['staff_code']に値を設定している箇所がありません。 どこか他の場所で設定しているのでしょうか。
ryouya

2020/09/19 08:12

ご連絡遅くなりすみません、ご回答ありがとうございますm(__)m ログインの処理をする際にセッションに下記のようにユーザーの要素を入れています。 ''' { $_SESSION['login']=1;//?? $_SESSION['staff_code']=$staff_code; $_SESSION['staff_name']=$rec['name']; set_flash('sucsess','ログインしました'); header('Location:staff_top.php?staff_code='.$staff_code.'&type=main'); //headerとは指定のパスへ飛ぶ命令ができる exit(); } ''' セッションが切れる前はフォローボタンがあるページにstaff_codeがあることは確認が取れています。 ※var_dump($_SESSION['staff_code']);のように値を確認しています。
guest

0

PHP

1$_SESSION

を使用する前に

PHP

1session_start();

する必要があるのではないでしょうか。
基本的な使用法

投稿2020/09/15 20:20

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

ryouya

2020/09/16 09:09

回答ありがとうございます! 一応セッション使用する際はファイル上部にsession_start();を記載しているのですが、 まだどこか抜けていますでしょうか。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問