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

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

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

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

Q&A

解決済

3回答

1169閲覧

現在のページに応じた条件分岐を作りたいです。

irukairuka

総合スコア15

PHP

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

0グッド

0クリップ

投稿2019/03/04 06:56

現在のページに応じた条件分岐を作っているのですが、変なことが起こりました。

現在のページは$url = `$_SERVER['REQUEST_URI'];で取得しますが、今回はひとまず
$url = '/topic/dog/';としています。

で、この$urlは「topicのページ」なので、<p>topicのページ</p>だけをechoしたいのですが、、

なぜか、<p>membersのページ</p>までがechoされるという状態です。

php

1<?php 2function my_is_page( $one, $three=null ) { 3 4 //URLを取得する 5 //$url = $_SERVER['REQUEST_URI']; 6 $url = '/topic/dog/'; 7 8 //URLに応じてページ分岐 9 $arr = explode( '/', $url ); 10 11 if( isset($arr[1]) && is_null($three) ){ 12 if( $arr[1] == $one ){ 13 return true; 14 } 15 } 16 17 if( isset($arr[3]) ){ 18 if( $arr[3] == $three ){ 19 return true; 20 } 21 } 22 23} 24 25 26if( my_is_page('topic') ){ 27 echo '<p>topicのページ</p>'; 28} 29 30if( my_is_page('members') ){ 31 echo '<p>membersのページ</p>'; 32} 33 34if( my_is_page('members','settings') ){ 35 echo '<p>members/settingsのページ</p>'; 36} 37 38?> 39

私の考えでは、$arr[1]引数$oneが等しいときだけtrueが返るハズなので、$url = '/topic/dog/';のときにif( my_is_page('members') ){}は反応せず、<p>membersのページ</p>までがechoされるのはおかしいのでは?と思うのですが、、

どうすればページ分岐が適切にできるでしょうか?

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

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

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

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

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

guest

回答3

0

PHP

1function my_is_page( $one, $three=null ) { 2 3 //URLを取得する 4 //$url = $_SERVER['REQUEST_URI']; 5 $url = '/topic/dog/'; 6 7 //URLに応じてページ分岐 8 $arr = explode( '/', $url ); 9 10 if( isset($arr[1]) && is_null($three) ){ 11 if( $arr[1] == $one ){ 12 return true; 13 } 14 } 15 16 if( isset($arr[3]) ){ 17 if( $arr[3] == $three ){ 18 return true; 19 } 20 } 21 22}

問題は二つ目の判定部分です。
explode('/', '/topic/dog/') の結果は、

PHP

1array(4) { 2 [0]=> 3 string(0) "" 4 [1]=> 5 string(5) "topic" 6 [2]=> 7 string(3) "dog" 8 [3]=> 9 string(0) "" 10}

となりますから、$arr[3] は空文字列です(意図としては $arr[2] をチェックしたいのでしょうか?)。そして PHP では論理値への変換を行う場合、次のものは FALSE となります。

  • 整数値の 0
  • 実数値の 0.0
  • 空文字列
  • 文字列としての "0"
  • 空の(要素数0の)配列
  • NULL

つまりこのif文が

if ($arr[3] == $three) { ↓ if ("" == NULL) ↓ if (FALSE == FALSE)

と変換されるので、成立するのです。

厳密な(型変換をしない)判定である === を使うと意図した動きになります。

投稿2019/03/04 07:17

編集2019/03/04 07:18
tacsheaven

総合スコア13703

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

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

irukairuka

2019/03/04 07:33

おおおお!わかりやすかったです。どうもありがとうございます。
irukairuka

2019/03/04 08:26 編集

メンバーごとのフロントページはどのようにしたらいいと思いますか?
tacsheaven

2019/03/04 08:12

フロントページと言うことは、 ・arr[1] が "members" で、 ・arr[3] が空文字列で、 ・arr[2] がメンバー名 という条件で判定すればよいのかと思います(2と3の順番が逆な理由は後述)。 ただこれを一つの if 文にまとめるのではなく、ネストさせた方がよいでしょう。1 と 3 は同時にチェックして、2 だけその中でチェックするようにします。そうするとメンバー名が増えても対応がしやすいです。
irukairuka

2019/03/04 08:26

ありがとうございます。さきほどはemptyが思いつかず追加で聞いてしまいましたが、下記で解決致しました。(メンバー名は飛ばしましたが、だいじょうぶですよねたぶん笑) ➀この条件を追加し if( isset($arr[1]) && $arr[1] == $one && $three == 'front' && empty($arr[3]) ){ return true; } ➁このように判定しました if( my_is_page('members','front') ){ echo '<p>membersのfrontページ</p>'; }
tacsheaven

2019/03/04 08:31

ん? なんか変なような…… if ($arr[1] == 'members' && $arr[3] == '') { if ($arr[2] == 'john') { return true; } if ($arr[2] == 'mike') { return true; } } return false; こんな感じですよ?
irukairuka

2019/03/04 08:34

あ、なるほど。そうすれば「メンバーそれぞれのフロントページ」が判定ができますね。私のはとりあえず「メンバーのフロントページ」としか考えておりませんでした。ありがとうございます。
tacsheaven

2019/03/04 08:38

もう少し判るようになると、メンバー名のリストを別のところから持ってきて、ループを組み合わせてチェックするとかいろいろやれるようになります。が、それはおいおい理解していけばいいでしょう。
irukairuka

2019/03/04 08:49

既存の関数があるのでなんとなくできそうです。今回はこれにて。引き続き挑戦してまいります。最後までお付き合い頂きまして、どうもありがとうございました。がんばります!
guest

0

ベストアンサー

こういうときこそデバッグです。
__LINE__は「現在のプログラムの行数」を出力してくれますので、
そちらも利用します。

php

1function my_is_page( $one, $three=null ) { 2 3 echo $one."\n"; 4 //URLを取得する 5 //$url = $_SERVER['REQUEST_URI']; 6 $url = '/topic/dog/'; 7 8 //URLに応じてページ分岐 9 $arr = explode( '/', $url ); 10 11 if( isset($arr[1]) && is_null($three) ){ 12 echo __LINE__."\n"; 13 if( $arr[1] == $one ){ 14 echo __LINE__."\n"; 15 return true; 16 } 17 } 18 19 if( isset($arr[3]) ){ 20 echo __LINE__."\n"; 21 if( $arr[3] == $three ){ 22 echo __LINE__."\n"; 23 return true; 24 } 25 } 26}

出力結果:

topic 13 15 <p>topicのページ</p>members 13 21 23 <p>membersのページ</p>members 21

2つ目、「my_is_page('members')」を実行したときに
21行目、23行目を通ってtrueを返していることが分かります。

php

1 if( isset($arr[3]) ){ 2 echo __LINE__."\n"; 3 if( $arr[3] == $three ){ 4 echo __LINE__."\n"; 5 return true; 6 } 7 }

$arrの[3]が存在していて、$threeと同じだったら、、、ですね。

では、membersのときだけここで何がきているか出すようにしてみましょう。

php

1 if($one === "members"){ 2 var_dump($arr); 3 if( isset($arr[3]) ){ 4 echo __LINE__."\n"; 5 if( $arr[3] == $three ){ 6 echo __LINE__."\n"; 7 return true; 8 } 9 } 10 }

出力結果:

members array(4) { [0]=> string(0) "" [1]=> string(5) "topic" [2]=> string(3) "dog" [3]=> string(0) "" } 23 25 <p>membersのページ</p>

はい。
$arrの3は""です。
一応、==で比較していると""とnullは同じとみなされます。
下記のように修正することで対応可能

php

1 if( isset($arr[3]) ){ 2 if( $arr[3] === $three ){ 3 return true; 4 } 5 }

なぜか?
/topic/dog/を/で分割されているわけですが、

[]/topic/dog/[]
↑[]で囲っているところが含まれるからなんですね
ミニマムコードで試すとこんな感じ。

php

1$url = '/'; 2$arr = explode( '/', $url ); 3var_dump($arr); 4/* 5array(2) { 6 [0]=> 7 string(0) "" 8 [1]=> 9 string(0) "" 10} 11*/

もしこの現象をなくしたければ「最初と最後は除く」みたいなのが必要かと思います。


蛇足:分岐入れてて更にifとか入れるのはいいですが、何も処理がないならまとめたほうが良い

php

1if( isset($arr[1]) && is_null($three) && $arr[1] == $one){ 2 return true; 3} 4if( isset($arr[3]) && $arr[3] == $three){ 5 return true; 6}

「その関数の全ての分岐を実行されない」こともあるので、一応明示的に
最後にreturn false は入れておいた方が良い。

投稿2019/03/04 07:19

m.ts10806

総合スコア80850

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

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

irukairuka

2019/03/04 07:35

これはすごい!デバッグの方法と流れを見せて頂き納得できました。__LINE__も便利ですね。ご丁寧にありがとうございます。大変勉強になりました。
m.ts10806

2019/03/04 07:36

解決されたようで何よりです。 デバッグは今後も活用してください。質問する前に解決できることも多くなるはずです
irukairuka

2019/03/04 07:38

はい!どうもありがとうございました。
guest

0

PHP

1$arr[3] === $three

投稿2019/03/04 07:04

yambejp

総合スコア114769

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

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

irukairuka

2019/03/04 07:36 編集

できました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問