#while文の条件式に=演算子が使える理由
比較演算子がなく、=の代入演算子のみで上構成されているwhile文を使いましたが理由がわかりません
PHPでmysqliを使用してデータベースを触っています。
mysqliとはあまり関係ありませんが、以下の時の、while文でなぜ=演算子によってwhile文が成立するのかが知りたいです。
不都合と緊急性はありませんが、モヤモヤするので知っているかた是非教えてください
php
1// クエリ文を作って 2$sql = "クエリ文"; 3 4// 実行して 5$res = $mysqli->query($sql); 6 7// 連想配列に直す 8$data = array(); 9while ($row = $res->fetch_assoc()) { 10 $data[] = $row; 11}
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答6件
0
ベストアンサー
正しく動作はするけど個人的には好みじゃないですね。
さて、以下のコードで分かるように…
php
1$a = $b = 1; 2echo '$a = ' . $a . "\n"; 3echo '$b = ' . $b . "\n";
代入結果は伝搬するんスね。
あと、評価は基本的に true か false なんスけど、それ以外のものが与えられた場合はどちらかに(無理やり)変換されちゃうんス。
そういう(ある意味)ダーティな規則を用いると短いコードが書けちゃったりしますが、それよりもっと分かりやすいコードがいいんじゃないかなあ。
投稿2021/03/16 11:40
編集2021/03/16 11:42総合スコア7460
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
回答ではないです。while ($row = $res->fetch_assoc())
という書き方がキライなので書きます!
基本的に php の条件式の中に代入演算子を混ぜなければならないケースはありません。
(ごく僅かに存在しますが、初学者ほど知らなくてよいケースです)
本件では、$res
というmysqli_result
つまり結果セットからループ毎に結果の行を連想配列で取得する操作をしていますが、結果セットはforeach
でほぼ同様のことが実現可能です。
例2 mysqli_result, iterator, mysqli_result::fetch_assoc() の使い方の比較
mysqli_result は、foreach を使って繰り返し処理をすることができます。 結果セットは、現在の位置に関わらず、最初の行から処理されます。
こちらがオススメです。
php
1$result = $mysqli->query($query); 2foreach ($result as $row) { 3 printf("%s (%s)\n", $row["Name"], $row["CountryCode"]); 4}
追記
ちょっとキライの根拠を補足しますね。
条件式に代入演算子を交えると、比較演算子のタイポが疑われます。
==
,===
を間違っちゃったんじゃないの?ってやつです。
syntax error にならないので、緩いテストだと通ってしまう事もあり、見かけるたびに「検証しなくては!」という義務感にかられる人も多いです。
また、この手のタイポ予測はチェックツールで監視している人も多く(現場のコーディング規約次第ですが)可能な限り使用をさけるのが良いです。
条件式に代入演算子の使用を許容するために「ヨーダ」とか言い出す人がいると最悪ですw
投稿2021/03/24 02:46
編集2021/03/24 06:19退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
=か使えるのは「式」として成立するからです。
whileの「()」は、ループ内のコード実行するかどうかの条件式を書きますよね。
条件式がtrueの時は実行する、falseの時は実行しない、です。
比較演算子も、条件満たしてたらtrue、条件満たさない時はfalseを返してます。
$row = $res->fetch_assoc()も同じようにtrue,falseで判別されます。
$res->fetch_assoc()は値がある場合は、$rowに代入され、その$rowは値が入っているのでtrueとなります。
$res->fetch_assoc()の最後は値がなくなり、nullを返します。$rowにnullが代入されるのですが、nullの入った$rowはfalseとなります。ここでwhileループは終了します。
条件式・ループ回数としては
while ($row = $res->fetch_assoc()) {
while ( $res->fetch_assoc()) {
どちらも同じで同じ回数ループしますが、$res->fetch_assoc()の戻り値をループで使うので$row = $res->fetch_assoc()とまとめてしまっている、ですかね。
投稿2021/03/16 00:40
総合スコア595
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
代入式の値は代入された値と同じです。$a=123
ならこの式が返す値は123です。
したがってwhile($row = $res->fetch_assoc()){
は、条件判定としてはwhile($res->fetch_assoc()){
と同じです。これに$rowへの代入というおまけが付いているということです。
こういう書法を知っているとコードを短くできるという利点があります。慣れないうちは危険なので無理やり真似る必要はありませんが、こういうやり方もあると頭の片隅に入れておくといいです。
投稿2021/03/15 18:57
総合スコア13692
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
これは、Perl言語におけるDBアクセスのイディオムに由来する書き方です。
PHPが普及するまで、Webアプリケーションでもっとも普及していた言語がPerlだったので、PHPはPerl言語の慣習を多くとりこんでいます。この書き方もそうです。
そして、PerlはC言語やsed、AWKなどの影響を受けています。C言語のイディオムでは、whileループの条件式に代入を用いることがよくあったので、PerlのDBアクセスのイディオムもその影響を受けています。
要は、その当時のプログラマーにとっては親しみのある書き方だった、ということですね。
投稿2021/03/23 23:40
総合スコア973
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
代入式の場合左辺の変数の値と右辺の式の値が等価になります
そのため
Whileのループ判定は左辺で行っても右辺で行っても等価となります。
したがって
右辺の式評価の結果を持ってループをしても
変数の値でループをしても
結果が等価になることを、処理系に指示することができるからです
逆にこれが嫌な場合は
代入を先に行い
値のみで明示的にループ判定をせよと記述するなり dowhileを使うなどして逆の処理が必要になります。
式でループするか値でループするかは意味論といえば意味論なのですが厳密にはことなるため
そういう仕様でありPHPはその仕様を引き継いでいるからです
投稿2021/03/24 00:04
総合スコア190
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。