PHP質問・雑談スレ 2【初心者お断り(ROM歓迎)】©5ch.io
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん 転載ダメ©2ch.net
2016/10/17(月) 21:44:12.59ID:???初心者お断り(ROM歓迎)と書いてますが、初心者用のスレが用意されているからで、
難しい質問や話題をしなければいけないわけではありません。
PHPマニュアルの読み方を概ね理解していて、関数リファレンスが正しく読める方用のスレです。
PHP未導入の方や、手取り足取りが必要な初心者の方はム板のくだスレへどうぞ。
http://echo.2ch.net/tech/ (【PHP】で板内を検索)
前スレ
http://tamae.2ch.net/test/read.cgi/php/1461283091/
その他リンク
・PHPマニュアル
https://secure.php.net/manual/ja/index.php
・コードテスト・貼り付け用
http://ideone.com/
・プログラミングのお題スレ Part8 (求PHPer参戦)
http://echo.2ch.net/test/read.cgi/tech/1444216746/
このスレで扱う話題
・PHPのコード,設定や設定値に関する質問
・常識的範囲内でのコードレビュー依頼・改良相談
・PECL,PEARに関する質問
・PHP新機能やPHP関連トレンドの話題
(FWや非公式ライブラリの話題や特徴比較は良いが使い方から先の話題は専スレへ)
・PHPのバグ発見報告・公式に報告する前の検証依頼
このスレで扱わない話題
・直接関係ない○○特有の質問(専スレへ)
(HH,エディタ,IDE,サーバ,OS,DB,SQL,FW,テンプレート,非公式ライブラリ・アプリケーション等)
・PHPの改造
0345nobodyさん
2016/11/11(金) 22:06:51.01ID:???$searchFilter = new $searchFilterClassName();
$searchFilter->filterAll($query, $requests);
こんな感じで呼び出すクラスを動的に変更してるけど、もしかしてバッドプラクティスになる?
0346nobodyさん
2016/11/11(金) 22:10:27.95ID:???命名が気持ち悪い
0348nobodyさん
2016/11/12(土) 08:29:00.73ID:???「直江山城守従五位下藤原朝臣兼続」と律儀に書きそうな所
0350nobodyさん
2016/11/12(土) 09:10:45.07ID:UTGbJvCcPHPも進化しててそう簡単には廃れないと思うよ
フレームワークなんてクラスと継承使いまくるし昔とは全然違う
JAVAっぽい感じすらある
もし他のやるってならrubyかパイソンかJAVAかな
PHPは簡単に始められるということで人によってレベルに差がありすぎる
フレームワークでクラス使えてDBやApacheまで理解して使えるならJAVAプログラマーと変わらないレベル
0351nobodyさん
2016/11/12(土) 09:31:50.95ID:???0352nobodyさん
2016/11/12(土) 10:24:09.54ID:???命名は、スコープを意識した方が良い。
例えば、$searchFilterClassName は目的のクラスをnewする時にしか使わないんじゃない?
そうすると、その変数の必要有効範囲は2行しかない。
もし、他の場所でクラス名を知りたければ
$searchFilter内で定義済み定数 __CLASS__ を使って参照できるから。
そんな、その場限りの変数に仰々しい名前をつけるのは無駄な上に
全く別の人がコードを読む時には
いかにも意味がありそうな命名なので追いかけてみたら、その場所でしか使っていなかったとかで
大して意味が無い余計な情報になってかえってコードが読みにくい。
そんなのは$classNameで十分。
俺は「使い捨てだ」ということを強調するために場合によっては1,2文字変数を使うこともある。
0354nobodyさん
2016/11/12(土) 11:53:15.24ID:???長い開発経験の中で出した、あくまでも俺の答えだから、そうは思っていないやつも居る。
だから「絶対」ではない。個人的意見だと思ってもらって構わない。
ただ、クソコードだなぁと思うコードの半分は
使い捨ての変数に$youAreFuckNSonOfABichみたいな命名をしている特徴がある。
Javaでプログラムを学んだJava脳の奴に多い。
もう半分のクソは本当にただのクソで、いかにもPHPerといったコード。
0355nobodyさん
2016/11/12(土) 12:03:17.81ID:UTGbJvCcうちのリーダーか?笑
使い捨て関数使ってるけど開発効率考えたらそれが良いと思う
使い回して深く追う可能性のあるものだけちゃんと名前付けておいた方が良いね
0356nobodyさん
2016/11/12(土) 12:07:06.42ID:UTGbJvCc自分やその時の現場のメンバーだけ使うものは一文字で良いだろうね
何かしらのツールで共有しておけば良い
0357nobodyさん
2016/11/12(土) 12:43:16.19ID:???他人が書いたコードリーディンングする時、重要なのは「その変数が何であるか」
「何が入っているかが分かる」事のみに着目して長ったらしい名前をつけられると、
ほんの数行先で出てきた変数が、
前に出てきたそれと同じなのか違うのかが把握できない。
大体、1つの処理単位で利用する変数はにた名前になりやすいから
名前が長いと余計わかりづらい。
人間が一目で判別できる文字数は5,6文字が限度だろう。
「その変数が何であるか分かる」ってことと「その変数に何が入っているか分かる」ってことはイコールではなく、
必要なのは「何が入っているかわかる」ことではない。
0358nobodyさん
2016/11/13(日) 01:59:25.88ID:???0359nobodyさん
2016/11/13(日) 09:57:04.08ID:???0361nobodyさん
2016/11/13(日) 14:33:14.76ID:???0362nobodyさん
2016/11/13(日) 15:27:12.88ID:???0363nobodyさん
2016/11/13(日) 16:12:35.87ID:???echo "{$fire}unko"
0364nobodyさん
2016/11/13(日) 19:55:24.39ID:???$c = $a. $b;
echo $c;
カンマは
echo $a;
echo $b;
0365nobodyさん
2016/11/13(日) 21:06:29.54ID:???これって意味あるんですか?
定数がすでにあった場合定義されませんが、期待している値じゃなかったらバグの原因になるだけなので、
逆にエラー出したほうがいいと思うんですが。
0366nobodyさん
2016/11/14(月) 01:32:44.29ID:???0367nobodyさん
2016/11/14(月) 04:03:26.34ID:???そのコード自体ををいじらなくても外側から上書きできるようになるってことだね。
0368nobodyさん
2016/11/14(月) 04:39:52.56ID:???動作結果は同じだけど意味合いが違うから使い分けが大事。
【ドットが適切な場合】
$message = 'My name is ' . $name;
echo $message;
↓省略
echo 'My name is ' . $name;
【カンマが適切な場合】
echo $errorCode;
echo $errorMessage;
↓省略
echo $errorCode , $errorMessage;
ただ、カンマの例の場合
$output = $errorCode . $errorMessage;
という考え方も出来るからカンマを使う場面ってのはそんなに無いと思う。
ってか自分は使ったこと一度もない。
0370nobodyさん
2016/11/14(月) 16:59:18.70ID:???require_onceってのもあるし、二重にrequireすること自体が問題。
0371nobodyさん
2016/11/14(月) 17:14:51.81ID:???requireするのが自分だけとは限らないし
することが可能ならそうされても大丈夫なようにしとけばいいじゃん
インクルードガードも否定派なの?
0372nobodyさん
2016/11/14(月) 19:07:26.76ID:???データベースからデータを引っ張って来て、<li>要素に入れて表示したいとします。
この場合、どういう風に組み立てたら良いでしょうか
functionかclassを作ったほうが良いのでしょうか?
以下のようなコードがどこかに入ると思いますが、どこに入れるとよいのでしょう
$li = "";
foreach($result as $key){
$li .= '<li>'.$key.'</li>';
}
phpはhtmlの前にまとめるのは何となく分かりました。
<?php
$pdo = new PDO(...);
$st = $pdo->prepare(...);
$st->execute();
$result = $st->fetchall(); //$result に結果が入る
$st->closeCursor();
?>
<html><body>
<ul>
//
<li>データをここに表示させたい</li>
<li>データをここに表示させたい</li>
<li>データをここに表示させたい</li>
</ul>
0373nobodyさん
2016/11/14(月) 19:29:21.64ID:???>> (static なメソッドにはアクセスできます)。
こう書いてあるけど、staticメソッドにインスタンス化したオブジェクトからアクセスするのってバッドプラクティスになる?
将来非推奨になっちゃったりとか
0374nobodyさん
2016/11/14(月) 19:51:29.20ID:???その程度の規模でも分離しよう
~~~~index.php
<?php
$pdo = new PDO(...);
$st = $pdo->prepare(...);
$st->execute();
$result = $st->fetchall(); //$result に結果が入る
$st->closeCursor();
include('templates/index.tpl');
~~~~templates/index.tpl
<html><body>
<ul>
<?php foreach ($result as $value): ?>
<li><?= $value ?></li>
<?php endforeach; ?>
</ul>
>>372
スタティックであることを明示出来ない点はデメリットだがそれが問題にならなければよい
あとC++とかでも同様に書けるからdeprecatedにはならないんじゃないかと
0376nobodyさん
2016/11/15(火) 00:44:40.64ID:???publicはメソッドのみ。プロパティには使わない
プロパティは基本privateにして、クラス内メソッドからアクセスする
継承させるつもりならメソッドでもメンバでもprodectedにする
という認識であってますか?
0377nobodyさん
2016/11/15(火) 01:06:52.72ID:???初心者お断りなんだがね・・・・
それは覚えるもんじゃなくて理屈で設定するもんだ
プロパティ間に関連がある(文字列とその長さとか)なら外部からそれぞれ勝手に変えられたら不味い, ならprivateにせねばならん
プロパティ単独で他と関係がなく, 書き換えられても問題ないならpublicなりprotectedなり好きにすれば良い
メソッドは基本的にそのクラスのオブジェクトに対する可能な操作なわけだから, 外部に公開する部分についてはpublicにする他ない
内部だけで利用するようなユーティリティメソッドであればpublicにする必要はない
protectedは「外部には公開しないが継承先クラスからは見えてよい」場合に設定するもの, インスタンス側のスコープからは見えない(publicを包含しない)
カプセル化の原則は「外部から見えるものは最小限に」。
見せても良いけど見せなくても良いなら見せない, privateにすべし。
どうしても必要な場合にprotected, publicと順にアクセス権を広げていく。
0378nobodyさん
2016/11/15(火) 03:25:11.75ID:???0379nobodyさん
2016/11/15(火) 10:05:33.84ID:???0381nobodyさん
2016/11/15(火) 11:52:22.08ID:???特定のクラスからしか操作したくないならprivateかprotectedにするけどさ、
OOPだと、DTOっつうものがあって、こいつはいろんなクラスをたらい回しされる。
そうすっと、仮にセッター作ってもどのみちいろんなところからいじられちゃうわけで、
もはや、privateやprotectedにする意味は殆ど無いし、むしろ、邪魔。
だから、用途に合った設定をすべきで
>publicはメソッドのみ。プロパティには使わない
みたいなステレオタイプな認識しかできないやつは、
そもそもグラマには向いてないのさ。
0382nobodyさん
2016/11/15(火) 12:16:50.98ID:???便利便利じゃないじゃなくてOOPの概念から離れちゃうってことね
とりあえず初心者は量産プログラマー目指して忠実にやったほうがいいと思うよ
実力伸ばすのは基本抑えてからでいい
0383nobodyさん
2016/11/15(火) 13:15:07.23ID:???0384nobodyさん
2016/11/15(火) 13:18:22.00ID:???理由は分からないけど周りに合わせる、なら別にいいある意味方針のカプセル化だ
みんなが好き勝手にコードを書くのが最悪
0385nobodyさん
2016/11/15(火) 13:21:22.86ID:???$users = $stmt->fetchAll(PDO::FETCH_CLASS, 'User');
のUserクラスにも、setter, getterを定義するの?
0386nobodyさん
2016/11/15(火) 13:28:22.94ID:???0389nobodyさん
2016/11/15(火) 14:32:40.91ID:???0390nobodyさん
2016/11/15(火) 14:33:21.93ID:???https://www.ogis-ri.co.jp/otc/hiroba/technical/concept.html
0391nobodyさん
2016/11/15(火) 14:55:04.23ID:???>>383はアホだからほっとけ
>>385
定義すれば型矯正ができるが、PHP様にはマジックメソッドというものがあるので
明示的にgetter/setterは作らない
0394nobodyさん
2016/11/15(火) 15:09:20.45ID:???__set()
0396nobodyさん
2016/11/15(火) 15:24:09.65ID:???https://twitter.com/s_osa_/status/515312406084345856?ref_src=twsrc%5Etfw
「外部に公開するインターフェイスを決定して、そのために必要な変数をプライベートで保持する」っていう感じ。
インターフェイスが先に来ることがわかっていれば>>395のように混乱することはない
0397nobodyさん
2016/11/15(火) 15:33:38.65ID:???別に混乱してないと思うが。
>>394は、
class User {}
と定義して
$users = $stmt->fetchAll(PDO::FETCH_CLASS, 'User');
を実行するという意味だと思うが、それだと
class User {
public $user_id;
public $name;
public ...
}
と同じ事になり、カプセル化に反するのでは?という疑問。
0398nobodyさん
2016/11/15(火) 15:56:55.53ID:???0399nobodyさん
2016/11/15(火) 16:08:24.97ID:???については多弁なんだな
0406nobodyさん
2016/11/15(火) 16:28:38.53ID:???0407nobodyさん
2016/11/15(火) 16:37:12.33ID:???0410nobodyさん
2016/11/15(火) 16:45:53.53ID:???しょうがねぇな、では、真面目に答える。
なんかうまく書き込みできねーから2回に分けてみるが、うまくいくかどうか。
> 385 : nobodyさん2016/11/15(火) 13:21:22.86 ID:???
> $stmt = $db->query('SELECT * FROM users');
> $users = $stmt->fetchAll(PDO::FETCH_CLASS, 'User');
> のUserクラスにも、setter, getterを定義するの?
>>385の流れの質問だったよな。
例えば users テーブルのカラムは
id:int
name:varchar(32)
gender:int
register_date:datetime
とする
0411nobodyさん
2016/11/15(火) 16:47:40.26ID:???この場合の User クラスは
class User
{
private $id = null; private $name = null; private $gender = null; private $register_date = null; public function __get($key){
if(!isset($key)){
throw new Exception("The key you specified is invalid.");
}
return $this->$key;
}
public function __set($key, $val){
switch($key){
case "id":
$this->$key = (int)$val; break;
case "name":
$this->$key = (string)$val; break;
case "gender":
$this->$key = (int)$val; break;
case "register_date":
$this->$key = new DateTime($val); break;
default:
throw new Exception("Invalid parameter has been given.");
}
}
}
こうすれば、fetchした時点で型付けされる。
俺はなんて優しいんだよ。ほかのバカどもは一生俺にひれ伏せ。
0412nobodyさん
2016/11/15(火) 16:48:50.77ID:???__get/__setの使い方はこれでわかんだろ。
0413nobodyさん
2016/11/15(火) 16:49:21.89ID:???興味がある人はそっち探して読むといいよ
例:
「Oh No! DTO!」??オブジェクトとデータ構造Add Star (2004年)
http://kakutani.com/20040227.html#p01
もうそろそろ馬鹿の一つ覚えのように「カプセル化」を連呼するのはやめようぜ (2007年)
http://blogs.wankuma.com/kacchan6/archive/2007/10/12/101603.aspx
0415nobodyさん
2016/11/15(火) 16:58:57.20ID:???0417nobodyさん
2016/11/15(火) 17:03:29.21ID:???>個別のgetter/setterとなんらかわらんわ
うわぁ、サル全開!
getterやsetterで同じこと実装してみろよ。
どうなるか予想つかないのかよゴミクズは。
0423nobodyさん
2016/11/15(火) 17:19:14.05ID:???$this->$key = (int)$val; break;
これが動作することってあるの?
0426nobodyさん
2016/11/15(火) 17:22:56.61ID:???0427nobodyさん
2016/11/15(火) 17:23:55.21ID:???0428nobodyさん
2016/11/15(火) 17:25:12.49ID:???0429nobodyさん
2016/11/15(火) 17:25:33.74ID:???0431nobodyさん
2016/11/15(火) 17:32:07.76ID:???未だにカプセル化で論争が起こっています
0432nobodyさん
2016/11/15(火) 17:34:26.74ID:???>>429-230 PHPマニュアルに記載されていない事なんてしりまっしぇーん
載ってからかたってくださぁい
0433nobodyさん
2016/11/15(火) 17:35:31.85ID:???0434nobodyさん
2016/11/15(火) 17:37:21.98ID:???http://php.net/manual/ja/pdostatement.fetch.php
PDO::FETCH_CLASSはプロパティセット後にコンストラクタ
逆にするにはPDO::FETCH_LATEを追加指定
0435nobodyさん
2016/11/15(火) 17:38:13.86ID:???0436nobodyさん
2016/11/15(火) 17:40:13.19ID:???使ったことがあれば FETCH_LATE が誤記だと気づくし、意図もわかる。
分からないってことは FETCH_PROPS_LATE を知らないし、もちろんそれを前提としてはいなかったってことだ。
0437nobodyさん
2016/11/15(火) 17:40:55.66ID:???対象がすり替わってる話なんか聞く耳もちまっせーん
今までの話に何の関係があるのかもわかりまっしぇーん
論旨をのべてくださーい
ばーか
0438nobodyさん
2016/11/15(火) 17:41:54.06ID:???これかっこいいよね。
0443nobodyさん
2016/11/15(火) 17:43:50.71ID:???つまりコンストラクタ呼び出し前にプロパティがセットされるから, 定義したマジックメソッドの__setter/__getterは呼ばれない
フェッチ時に型固定は実現されない
0444nobodyさん
2016/11/15(火) 17:45:30.85ID:???あほなの?
じゃあ、その後でプロパティ再セットすればいいだけじゃん。それで型強制される。
それがお前の答えだったの? 本当のノータリンだったの?
■ このスレッドは過去ログ倉庫に格納されています