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

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

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

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

コーディング規約

コーディング規約とは、コードの書き方についての決め事のことです。 文法のことではなく、そのチームなどの中の約束事としてどのような書き方で行うかを定めるもの。 項目の例として、関数や変数の命名規則、コーディングのスタイル、括弧やインデントの書き方などが挙げられます。

Q&A

解決済

2回答

2972閲覧

PHPのこのコード、もっと良い書き方はありますか?

argius

総合スコア9388

PHP

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

コーディング規約

コーディング規約とは、コードの書き方についての決め事のことです。 文法のことではなく、そのチームなどの中の約束事としてどのような書き方で行うかを定めるもの。 項目の例として、関数や変数の命名規則、コーディングのスタイル、括弧やインデントの書き方などが挙げられます。

3グッド

4クリップ

投稿2016/02/20 05:25

初めてPHPを書いてみたんですが、こんな感じで問題ないでしょうか。
動作は確認済みです。

PHPは情報もバージョンもたくさんありすぎて、どれを参考にして良いのか選ぶのが難しいです。
バージョンによって、非推奨の関数や書式などがあるんだと思いますが、それも良く分かりません。
あと、ifforeachが入れ子になっているところとか、インデントとか、これで良いでしょうか。

...

使っているPHPのバージョンは5.4.x, 5.5.x, 5.6.xです。

よろしくお願いします。

  • 書いてみたコード

lang

1<?php 2 3// $json = file_get_contents("..."); 4$json = '{"status":200,"user":"argius","data":[{"aaa":1},{"bbb":2}]}'; 5$obj = json_decode($json); 6 7$status = $obj->{"status"}; 8$user = $obj->{"user"}; 9$data = $obj->{"data"}; 10 11 ?> 12<!DOCTYPE html> 13<html lang="ja"> 14<head> 15<meta charset="utf-8"/> 16<title>test</title> 17</head> 18<body> 19<?php if ($status === 200) : ?> 20<p>ユーザー:<?php print $user; ?></p> 21<p>データ</p> 22<table> 23<thead> 24<th width="85">key</th> 25<th width="75">value</th> 26</thead> 27<tbody> 28<?php 29foreach ($data as $row) { 30 foreach ($row as $key => $value) { ?> 31<tr> 32<td><?php print $key; ?></td> 33<td><?php print $value; ?></td> 34</tr> 35<?php 36 } 37} 38 ?> 39</tbody> 40</table> 41<?php else : ?> 42<p>予期しないエラーです。(ステータス: <?php print $status; ?>)</p> 43<?php endif; ?> 44</body> 45</html>
takotakot, nnahito, miyabi-sun👍を押しています

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

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

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

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

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

guest

回答2

0

ベストアンサー

全体的なインデントに関しては問題ないと思います。PHP の閉じタグはインデントしないのが一般的だと思いますが……。

lang

1<?php 2?>

まず、json_decode が失敗した場合の例外処理を行うと良いと思います。
これを行わないと JSON に不正な値が入っていたときに予期せぬ動作を引き起こします…。

lang

1<?php 2$status = 200; 3$obj = json_decode($json); 4if ($obj === null) { 5 $status = 500; 6}

それと、各々の出力するところで htmlspecialchars が呼び出されていないのが気になりました。これをしないとたとえば $user<script>alert(0);</script> といった文字列が入っていたら、予期せずスクリプトが実行されることになってしまいます。

次のような関数を定義して、すべての出力時にこれを通すようにすることを強くおすすめします。

lang

1<?php 2// エスケープ関数 3function h($str) { 4 return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); 5} 6?> 7 8<!-- 実際には次のように使う --> 9<p><?php print h($key); ?></p> 10 11<!-- echo 短縮構文を使用すると次のように書けます --> 12<p><?= h($key) ?></p>

次に、冒頭のプロパティの部分ですが以下の書き方のほうが一般的です。

lang

1<?php 2$status = $obj->status; 3$user = $obj->user; 4$data = $obj->data;

また、これは特に時間のかかる処理でもないので変数に代入せずに、それぞれの使用する箇所でたとえば

lang

1print $obj->status;

としたほうが把握するべき変数が少なくなるので、後で読むときにコードを追いやすいと思います。

投稿2016/02/20 05:45

chitoku

総合スコア1610

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

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

argius

2016/02/20 09:08

回答ありがとうございます! > PHP の閉じタグはインデントしないのが一般的だと思いますが……。 そうなんですか。 私はテンプレート言語では2カラム目に記号があるほうが見つけやすいので、そうする癖がついてしまって、ついそう書いていました。 その書き方に合わせます。 > json_decode が失敗した場合の例外処理を行うと良いと思います。 これは要りますね! $obj === nullで判断すれば良いんですね。 > エスケープ関数 これも要りますね。 デフォルトでエイリアスhが用意されているわけではないんですね。 > 冒頭のプロパティの部分ですが以下の書き方のほうが一般的です。 これで書けるんですか!? もしかして、これは比較的新しいバージョンで書けるようになったんでしょうか? > これは特に時間のかかる処理でもないので変数に代入せずに、... 今回の例では、$statusについては、何度か使うのと、APIの結果が取得できない場合に上書きするので、変数にしています。 $userは一度しか出てきませんし、こちらは$obj->userでも良いかなと思いました。 大変参考になりました。ありがとうございます。
chitoku

2016/02/20 09:18

デフォルトで h が用意されていれば便利なんですけどね…。 CakePHP といったフレームワークでは h があったりします。 プロパティの記法についてはおそらく PHP にクラスができた当初からこれで書けるはずです(PHP 4.4.9 で試しましたが動きました)。 何度か使うという理由ではプロパティをそのまま $obj->status で参照するべきかと思いますが、上書きするのであれば確かに変数のほうが良いと思います。
argius

2016/02/20 12:55

h()関数、CakePHPにはあるんですね。 > プロパティの記法についてはおそらく PHP にクラスができた当初からこれで書けるはずです なるほど...参考にしたサイトでは$obj->{"status"}と書かれていたので、それが普通だと思っていました。 適当に検索するより、公式の言語リファレンスを読んでみたほうが良さそうですね。
guest

0

全体的に自分の正義に基いて書いてますので、
参考程度に必要な箇所だけ取り入れてください。

使っているPHPのバージョンは5.4.x, 5.5.x, 5.6.xです。

もう既に5.4はサポート対象外です。
5.6も近い将来死ぬので、出来る限り新しい物を使っていったほうが良いです。


foreachですが私ならこう書きます。

PHP

1<?php foreach ($data as $row): ?> 2 <?php foreach ($row as $key => $value) : ?> 3 <tr> 4 <td><?= $key ?></td> 5 <td><?= $value ?></td> 6 </tr> 7 <?php endforeach; ?> 8<?php endforeach; ?>
  • 上で if: endif; を使っているのなら foreachを閉じるのはendforeach
  • 5.4以降は <?= xxx ?> のショートタグはデフォルトで有効、echoは読みづらいので積極的に採用していい
  • PHPのテンプレート形式で書く際、ifやforeachを開いて閉じる際、タグの入れ子は滅多に発生しないので字下げ対象とすると美しい

json_decodeのエラーの件ですが状況によります。
例えばコメントアウトされてない今回の本コードではリテラルの文字列で書かれてエラーが発生するわけないのでエラー処理を書かずに信頼すべきでしょう。

file_get_contentsもURL入れた場合と、ローカルのファイルパス入れた場合も挙動が異なります。
URLの場合は戻り値期待出来ない事もあるのでエラー処理やJSONなのかの確認はマスト。

逆にファイルなら、JSONファイルじゃないものをそもそもファイルとして保存すんなって話で保存時にしっかり見るべき、出力時に見はじめると二重チェックで無駄な処理。
データベースのユーザー情報だって普通信頼するでしょ?
信頼出来ないようなデータがサーバーに保存されて大事に扱われてるシステムなんて信頼出来るか?って話になっちゃうしね!

chitokuさんも突っ込んでるけど、出力する際はXSS対策にhtmlspecialcharsは入れるべき。
これはDBに突っ込む前ではなく出力時につけるもの。
JSONはJSONという書式で書かれたデータなだけなんで、HTML評価前提の形式に勝手に変えるべきじゃないからね。

投稿2016/02/20 14:36

miyabi-sun

総合スコア21145

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

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

argius

2016/02/21 07:01

回答ありがとうございます! > もう既に5.4はサポート対象外です。 > 5.6も近い将来死ぬので、出来る限り新しい物を使っていったほうが良いです。 5.6はあと1年は大丈夫みたいですね。 可能であれば新しくしてみます。 > foreachですが私ならこう書きます。 ショートタグ良いですね。 他のテンプレートなら使える記法なので、できるとは思っていましたが。 字下げ、HTMLのと合わせてすると綺麗に見えますね。 endforeachも使えると思っていましたが...字下げの件と合わせると、とてもしっくりきました。 > json_decodeのエラーの件ですが状況によります。 WebAPIのURLを想定しています。 そのままでも動かせるように、直接JSONを文字列で書いておきました。 説明をコメントとして書いておいた方が良かったですね、すみません。 > 出力する際はXSS対策にhtmlspecialcharsは入れるべき。 おっしゃるとおりです。 必要性は理解していましたが、どの関数を使えば良いか分からなかったので...
miyabi-sun

2016/02/23 04:52

json_decodeの下りですが、理解してるつもりですがちょっと書き方がまずかったかもしれませんね。 file_get_contentsはマシン内部のファイルも開いてくれますし、URL渡せばhttp通信を行ってくれる汎用的な関数なので、 何の内容を疑うべきか、何を信じるかの(僕が考える最強の)基本的な考えを記載しております。 既存のプロジェクトの方針や、argiusさん自身が思う所もあると思いますので、 参考になった部分だけ参考にしてくださいね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問