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

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

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

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

3回答

2443閲覧

会員登録なしでお気に入り機能を実装したい ajax

brebre

総合スコア29

PHP

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

2クリップ

投稿2017/09/19 03:51

編集2017/09/19 07:54

【概要】
会員登録なしでもお気に入り機能を実装したい

【現状】
お気に入りに追加するボタンを押すことで、お気に入りへの追加はできる。
また、リロード後にもう一度押すとお気に入りから削除もできる。

【問題点】
・お気に入りに追加後、リロードせずにもう一度同じボタンを押すと、
「お気に入りの削除」ではなく、再度「お気に入りへの追加」が起こってしまう。
・お気に入りの削除も同様。

【実現したいこと】
・ページ遷移やリロードせずにお気に入りの追加・削除ができるようにしたい。

【現在のコード】

index.php
(headや細かい点は省略)

php

1<?php 2 session_start(); 3 require_once("config.php"); 4 5 $favorite = explode("/",$_COOKIE["favorite"]); 6?> 7 8<script> 9$(".favborite_btn").find("a").click(function(){ 10 if($(this).hasClass('add_fav')) { 11 $(this).text("お気に入りに追加"); 12 $(this).removeClass('add_fav'); 13 $(this).unbind("click"); 14 } else { 15 $(this).text("お気に入り"); 16 $(this).addClass('add_fav'); 17 $(this).unbind("click"); 18 } 19 }); 20</script> 21 22<div class="favorite_btn"> 23 <?php if(!in_array(1, $favorite)): ?> 24 <a onClick="add_fav(1); ?>); return false;">お気に入りに追加</a> 25 <?php else: ?> 26 <a onClick="remove_fav(1); return false;" class="add_fav">お気に入り</a> 27 <?php endif; ?> 28</div>

javascript

1function add_fav(id){ 2 $.ajax({ 3 type: "POST", 4 url: "add_favorite.php", 5 data: { 6 "id" : id 7 }, 8 success: function(data){ 9 alert("お気に入りに追加しました"); 10 } 11 }); 12} 13function remove_fav(id){ 14 $.ajax({ 15 type: "POST", 16 url: "remove_favorite.php", 17 data: { 18 "id" : id 19 }, 20 success: function(data){ 21 alert("お気に入り削除"); 22 } 23 }); 24}

add_favorite.php

php

1<?php 2require_once("config.php"); 3 4 $favorite = ""; 5 if ( isset($_COOKIE["favorite"]) && isset($_POST["id"]) ) { 6 $favorite .= $_COOKIE["favorite"]; 7 $favorite .= "/" . $_POST["id"]; 8 } else if ( isset($_POST["id"]) ) { 9 $favorite .= $_POST["id"]; 10 } 11 12 setcookie("favorite", $favorite, time() + 60*60*24); 13 14?>

remove_favorite.php

php

1<?php 2session_start(); 3 4 $favorite = explode("/",$_COOKIE["favorite"]); 5 if (count($favorite) > 0) { 6 $idx = 0; 7 foreach ($favorite as $val) { 8 if ($val == $_POST["id"]) { 9 unset($favorite[$idx]); 10 } 11 $idx++; 12 } 13 } 14 $favorite_str = implode("/", $favorite); 15 setcookie("favorite", $favorite_str, time() + 60*60*24); 16 17 18?>

希望する機能を実装するためのコード等をご教授いただけますと幸いです。
よろしくお願いいたします。

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

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

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

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

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

guest

回答3

0

ベストアンサー

config.phpに何が書いてあるか気になるところではありますが、
有効期限があるCOOKIEやSESSIONではなくブラウザ側に保管するLocalStorageを利用されては?
javascriptなどで明示的に削除するかユーザー自身がブラウザの開発ツールで削除(かブラウザ自体をアンインストール)するまでは永続的です。

サンプルソース

Cookie読む部分とHTML(<?php冒頭と途中のHTML省略)

php

1$favorite = []; 2if(array_key_exists("favorite",$_COOKIE)){ 3 $favorite = explode("/",$_COOKIE["favorite"]); 4} 5 6$add_disp = ""; 7$remove_disp = ""; 8$none = ' style="display:none;"'; 9if(!in_array(1, $favorite)){ 10 $remove_disp = $none; 11}else{ 12 $add_disp = $none; 13} 14?> 15<div class="favorite_btn"> 16 <a onClick="add_fav(1); return false;" id="add_fav"<?=$add_disp?>>お気に入りに追加</a> 17 <a onClick="remove_fav(1); return false;" id="remove_fav"<?=$remove_disp?>>お気に入り</a> 18</div>

ajaxに送る部分

javascript

1function add_fav(id){ 2 $.ajax({ 3 type: "POST", 4 url: "add_fav.php", 5 data: { 6 "id" : id 7 }, 8 success: function(data){ 9 $("#remove_fav").show(); 10 $("#add_fav").hide(); 11 alert("お気に入りに追加しました"); 12 } 13 }); 14} 15function remove_fav(id){ 16 $.ajax({ 17 type: "POST", 18 url: "remove_fav.php", 19 data: { 20 "id" : id 21 }, 22 success: function(data){ 23 $("#remove_fav").hide(); 24 $("#add_fav").show(); 25 alert("お気に入り削除"); 26 } 27 }); 28} 29

cssのadd_favクラスが何を指定しているか分かりませんが、
もしshow,hideしていたり何かしらボタン装飾しているようであれば、click時のイベントでclassの付け外しするのではなく、
ajaxのsuccessを以てclassの付け外しすべきと思います。
万が一、ajaxが失敗した際に、「追加しました」「削除しました」の文言がalertされないのに
装飾が変わっているということがあるのではと思います。

と、いうか、ご提示の組み方だとどちらかしかHTMLに出てないので、画面をリロードしない限りは
リンクの見た目は変わってても、ajaxが片方しか呼び出されないようになっていると思いますよ。
つまり、COOKIEに保存前だと常に「お気に入りへの追加」だけが起こっている状況ですね。

投稿2017/09/19 04:41

編集2017/09/19 07:16
m.ts10806

総合スコア80850

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

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

brebre

2017/09/19 06:40

ご回答いただきありがとうございます。 config.phpには特別な記述はないので、今回は無視していただいて良いかと思います。 おっしゃるように、LocalStorageを利用した方が良いとは思うのですが、可能であれば上記のコードを修正し、COOKIEを用いて実装したいと考えております。 もしご教示いただけるのであれば、よろしくお願いいたします。
m.ts10806

2017/09/19 06:52

了解です。少しお待ちください。 ただajaxで「add_fav.php」で呼び出しておきながら質問本文では「add_favorite.php」と書かれています。どちらが正しいのでしょうか?
m.ts10806

2017/09/19 06:56

> <a onClick="add_fav(1); ?>); return false;">お気に入りに追加</a> この部分、 HTMLおかしくないですか?
m.ts10806

2017/09/19 06:58

初期アクセス時はCOOKIEにfavoriteがないのでissetとかarray_key_existsとかで確認しておいたほうが良いですね。 たぶん、HTML直せば想定通りに動きます。 ブラウザの開発ツールでエラー出てますよね。
m.ts10806

2017/09/19 07:01

上記踏まえて「私ならこう書く」サンプルコードを提示しますので少々お待ちを。
brebre

2017/09/19 07:56

申し訳ございません。add_fav.phpではなく、add_favorite.phpが正しいです。 サンプルコードをご提示いただけるとのこと、ありがとうございます。 お手数おかけしますがよろしくお願いいたします。
m.ts10806

2017/09/19 08:19

既に提示済みですのでご確認ください。 今回はそもそもHTMLにミスがあったことでjavascriptが正常に動作していないことが原因でした。 htmlコードの中にphpコードを混在させる場合は、なるべく簡潔な内容にとどめて置いた方がミスが減り、可読性も良くなります。 私が提示したコードでは「変数をechoする」のみとしてifなどのロジック部分は冒頭で済ますようにしています。
m.ts10806

2017/09/19 08:23

> add_fav.phpではなく、add_favorite.phpが正しいです。 すみません。サンプルコードでは上記は加味していないので、 私のサンプルコードを利用される際はご自身の環境にあわせて調整してください。
brebre

2017/09/20 12:32

ご提示いただきましたコードを試してみたところ、希望する動きを実現できました。 ありがとうございました!
guest

0

ちょっと状況がわからないのですが
とりあえずセッションで1アクセスに対する継続性は担保できるでしょう
ただしユーザー登録がなければそのユーザーが継続的にアクセスしているか
どうかは判断できません
セッションの有効期限がきれれば別ユーザーと判断されるでしょう

投稿2017/09/19 04:27

yambejp

総合スコア114769

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

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

brebre

2017/09/19 06:42

しっかりとしたお気に入り機能であればユーザー登録等検討すべきだと思います。 ただ、今回は可能であればCOOKIEで実装したいと考えており、もし上記のコードを修正するだけで実装できるならそうしたいところです。 ご教授いただけますと幸いです。 よろしくお願いいたします。
guest

0

COOKIEに保存するだけならajaxは不要だと思います。
http://qiita.com/takanorip/items/4e23b803bb1393176636

PHP側でCOOKIE保存以外の処理もする予定で、Ajaxも必須要件なのでしょうか?


以下追記

COOKIEの操作をするだけなら、Ajaxで通信挟むよりJavaScriptだけで完結したほうが通信リソース/サーバリソースを使わないのでいいと思います。

これ以上は本題から外れてしまうため、Ajax使わない場合のサンプルだけ提示します。

動作デモ
https://jsfiddle.net/2kkphpyd/

HTML

1<a href="#" class="favorite add_fav" data-id="1">お気に入りに追加</a><br> 2<a href="#" class="favorite add_fav" data-id="2">お気に入りに追加</a><br> 3<a href="#" class="favorite add_fav" data-id="3">お気に入りに追加</a><br>

JavaScript

1$(function(){ 2 $(".favorite").on('click', function(){ 3 if ($(this).hasClass("add_fav")) { 4 addFavorite( $(this).data('id')); 5 elementLookFavorite(this, true); 6 } else { 7 deleteFavorite( $(this).data('id')); 8 elementLookFavorite(this, false); 9 } 10 11 return false; 12 }); 13 14 var elementLookFavorite = function(targetElement, isfavorite) { 15 if (isfavorite) { 16 $(targetElement).text("お気に入り解除"); 17 $(targetElement).toggleClass('add_fav', false); 18 } else { 19 $(targetElement).text("お気に入りに追加"); 20 $(targetElement).toggleClass('add_fav', true); 21 } 22 }; 23 24 var addFavorite = function(id) { 25 var fav = loadCookieFavorite(); 26 if (fav.indexOf(String(id)) === -1) { 27 fav.push(id); 28 saveCookieFavorite(fav); 29 } else { 30 window.alert('すでにお気に入りに入っています'); 31 } 32 }; 33 34 var deleteFavorite = function(id) { 35 var fav = loadCookieFavorite(); 36 var idx = fav.indexOf(String(id)); 37 if (idx !== -1) { 38 fav.splice(idx, 1); 39 saveCookieFavorite(fav); 40 } 41 }; 42 43 var saveCookieFavorite = function(favArr) { 44 document.cookie = "favorite=" + favArr.join('/'); 45 }; 46 47 var loadCookieFavorite = function() { 48 var cookies = document.cookie.split(';') 49 50 for (idx in cookies) { 51 if ( ! cookies.hasOwnProperty(idx)) { 52 continue; 53 } 54 55 if (cookies[idx].indexOf('favorite=') == 0) { 56 var favStr = cookies[idx].substr('favorite='.length); 57 return (favStr.length==0) ? [] : favStr.split('/'); 58 } 59 } 60 61 return []; 62 }; 63});

投稿2017/09/19 14:24

編集2017/09/20 01:49
rkojima

総合スコア421

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

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

brebre

2017/09/20 12:33

コードまでご提示いただきありがとうございます。 おっしゃるようにAjaxは必須ではないかもしれません。 今回は既存のコードとの兼ね合いからAjaxを利用した内容で実装しましたが、今後は効率性等考えてコーディングしようと思います。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問