すみません、よろしくお願いします。
function readLines(string $path){
$i=0;
$file=fopen($path,'rb') or die('ファイルが見つかりません');
while($line=fgets($file,1024)){
yield $line;
}
fclose($file);
}
$gen=readLines('sample.txt');//***
foreach($gen as $line){
print $line.'<br>';
}
?>
読みだす対象ファイルは10行あります。
***の部分なのですが、$genで関数readLine()を1度呼び出して
対象ファイルから一行読みだしているように思えるのですが、
実際には、対象ファイルの全行を読みだしています。
$genで全行(10行)格納できているのは、どんな働きがあってのことなのでしょうか?
>>953
たった8行しかない関数なんだから
自分で1行ごとに何しているかを調べてみよう >>953
while ($line=fgets($file,1024)) { }
がループ処理だって事も分からないのはやばいぞ
もう少し頑張れw
このコードはだめだな
while($line=fgets($file,1024))
これだと 0 だけとか改行だけの行があったらそこで処理が止まる
同じように書くなら
while (($line = fgets($file, 1024)) !== false) { }
こう書かないと駄目
PHPerはよく if ($hoge = fuge()) みたいな書き方をするけど
分かってる上で手抜きでそう書くなら別にいいが
分かってないならそんな書き方はやめるべき ジェネレータ使ってるから一見何してるか分かりにくいように見えるかもね
とはいえ便利だし1行ずつ読めば難しくない
ifの条件文中で代入するのはむしろCでよく見た
>>957
swiftとかpythonだとこういう書き方はできないからね(代入式が値を返さない)
そのおかげでヨーダ記法みたいなヘンテコリンな書き方をしなくてもミスが防げるんだけど
一長一短だしこの書き方を全否定してるわけじゃないってことで
perlのワンライナーが気持ちいいってのもよく分かるが
人が書いたものは見たくないというのもよく分かるw すまん下の2行
全然関係ない文章が入ってしまった
書こうと思って削除した文章がクリップボード履歴からコピペされてしまった
0962デフォルトの名無しさん (ワッチョイ 5b4b-YrFS)2018/11/09(金) 16:59:43.84ID:aAkZVDrn0
PHPは大っ嫌いだけどLaravelは好き
0963デフォルトの名無しさん (ワッチョイ 5b4b-YrFS)2018/11/09(金) 17:13:56.97ID:aAkZVDrn0
セミコロン消えろ
なぜ文字列結合を . にしちゃったんだろう
フレームワークを通さずにドットチェーンでサクッと書きたい時に悲しくなっちゃう
>>953
$gen=readLine('sample,text'); は、$genに関数を入れてるだけで、
書き換えるのなら
foreach(readLine('sample.text') as $line){
print $line'.<br>';
}
ということでは? >>966
ありがとうございます。変数に関数を入れられるのですね。
書き換えられた方はテキストの別のページに載ってるのと似ているので理解できました。
すっきりしました。ありがとうございました。 >>967
別の人も書いてるけどジェネレーター(yield)を使ってて分かりにくいなら
yield使わずに同じことやってみたらいいかも >>968
ありがとうございます。
各yieldの前後や、関数の呼び出し元に
print文でどこを実行しているのかを表示させるようにして確認しました。
yield fromを混ぜ込んだ文も、同様に処理するようにしたら
ずいぶん理解できるようになりました。
皆様、ありがとうございます。 0970デフォルトの名無しさん (ワッチョイ f380-9/Uq)2018/11/10(土) 22:20:51.20ID:16GnFLu/0
$gen=readLine('sample,text');
これで代入されてるのは関数じゃなくてジェネレータ関数が返す反復可能なオブジェクト(への参照)かな
ジェネレーター関数を呼び出したのをvar_dumpするとこんな感じだわ
object(Generator)#1 (0) {}
0971デフォルトの名無しさん (ワッチョイ 5b4b-YrFS)2018/11/11(日) 16:39:55.95ID:kuiXddTN0
Laravelのログイン処理をゼロから解説してる学習リソースありますか?
青い本とオレンジ色の本
Amazonで探せばすぐにわかる
>>974
こんな性格じゃそりゃいつまで経ってもゴミのままだわな よろしくお願いします。
for($i=1;print"{$i}<br>",$i<6;$i++);
for($i=1;$i<6,print"{$i}<br>";$i++);
前者は、1〜6までをプリントしますが、後者は無限にプリントされてしまいます。i++が6を超えてしまうのはなぜなのでしょうか?
>>978
ありがとうございます。
判定がtrueになり続けてしまうということなのですね。
もう一つ質問があります。
class A{
private $B;
public function __construcr($C){
$this->B=$C;
}
というコードなのですが、classAのフィールドで変数$Bを宣言して
関数のコンストラクタの$thisで、変数$Bに引数を代入してますが
この時、変数Bの$が取れているのはどういう仕様なのでしょうか? $が取れていることで可変関数を使える仕様になっている
>>982
ありがとうございます。
可変関数は、$変数に関数名を格納して使うものだと理解していました。
もう少し、可変関数に関して調べてみます。 $db=getDb();
$opDB=$db->prepare('SELECT * FROM sample WHERE id=?');
$opDB->bindValue(1,$_GET['id'] ?:1);
このコードから質問お願いします。
2行目の id=? は、ワイルドカードのようなものですか?
3行目のbindValueの一つ目のパラメータの1は、何を指しているのでしょうか?
返答ありがとうございます。
id=? っていうのは、どういう働きをするコードなのでしょう
一つ目とか、bindValue(1,$_GET['id']);の、'1'です
>>984
>>986
SELECT * FROM sample WHERE id=?
というSQLの中で使われている「?」はプリペアドステートメントというもの
http://php.net/manual/ja/pdo.prepared-statements.php
?だと理解し難いなら名前付き(例えば今回なら :id とか)にした方が理解しやすいと思う
$hoge = $_GET['id'] ?: 1;
はエルビス演算子という三項演算子を省略した書き方
可読性が悪いのであんまり使わない方が良いと思う
・同じ事を三項演算子で書くなら
$hoge = ($_GET['id']) ? $_GET['id'] : 1;
・同じ事をif文で書くなら
if ($_GET['id']) {
$hoge = $_GET['id'];
} else {
$hoge = 1;
}
だが、このケースでは、こんな書き方をしてはいけない。
(続く) (続き)
$_GET['id']が定義されていない事を考慮した正しい書き方は
・PHP7以降ならNULL合体演算子を使って
$hoge = $_GET['id'] ?? 1;
・↑が分かり難いなら
$hoge = (isset($_GET['id'])) ? $_GET['id'] : 1;
・↑でも分かり難いなら
if (isset($_GET['id'])) {
$hoge = $_GET['id'];
} else {
$hoge = 1;
}
このケースでエルビス演算子をこんな使い方するような糞コードは、あんまり参考にしない方がいい
>>977も読んだが、エルビス演算子の使い方といい
いったい何を参考にしてこんなコードを書いてるんだろうか
もし本を参考にしてるなら焼き捨てた方がいいレベルで酷い
クイズ的に質問してるなら面白いけどw 演算子の説明だけだとシンプルで理解しやすいけど実用性ではクソ
実用性重視の説明だと本来説明したいもの以外の説明で蛇足だらけで
紙面使いすぎでクソ
というジレンマなんやろ
0991デフォルトの名無しさん (ワッチョイ 6fe7-sCK9)2018/11/27(火) 18:08:09.22ID:MA03kwvb0
$input = trim(fgets(STDIN));
while($input)
{
echo $input;
}
これってwhileの式のところでは$inputの中が空かって判断してるの?そういう機能がついてるのか?
>>984
SELECT * FROM sample WHERE id=?
id=? は、placement。
? の所に、値が入る
SQL injection 対策
例えば、単純な文字列をつなげて、問い合わせると、
? が「1; DROP TABLE 何々」とか、クラッカーに入力されると、
「SELECT * FROM sample WHERE id=1; DROP TABLE 何々」のように、
; で、危険なSQL文をつなげてくる
placement で、SQL文をつなげられないようにしている >>991
そのコードだと、trim(fgets(STDIN))の値が (bool) true であった場合に永久ループになるw
実際は
while ($input = trim(fgets(STDIN))) {
echo $input;
}
こう書くべき処理なのでは? 0994デフォルトの名無しさん (ワッチョイ 6fe7-sCK9)2018/11/27(火) 19:53:06.64ID:MA03kwvb0
while分の中では$inputをbool型にして判定してるわけか?
0995デフォルトの名無しさん (ワッチョイ ffd2-f63u)2018/11/27(火) 22:02:27.91ID:7ygBETe/0
空文字がFalse判定されることを利用して
空行入力で終わるようにしてるんだろうけど
ゼロとかもFalse判定されて終わっちゃうんじゃないか
試してないけど
Ruby では、nil, false の偽が2つだけ。
一方、JavaScript, Python, PHP などは、偽が10個ぐらいあるから、超危険!
基本的に、Ruby 以外は、バグってどうしようもない
>>987
ありがとうございました。プレイスホルダなのですね。
prepareでSQLを用いて、プレイスホルダを使うとき、
SQL文の中で、左から数えたプレイスホルダの順番を、
bindValueのカッコ内の数値で指定してバインドする、ということもわかりました。
?:や??:の解説もありがとうございました。
>>989
独習phpというテキストを使っています。
>>992
ありがとうございます。
prepareステートメントが悪意ある入力に対策しているとテキストにも書いてありました。
皆様、ありがとうとざいました。
今のテキストを読み終えたら、もう少しテキストを吟味して、違うテキストを探してみようと思います。 >>994
そういう事
ただ>>995,996の言う通りなので
while (($input = trim(fgets(STDIN))) !== false) {
echo $input;
}
こう書くのが正しい
(なんか前にも似たような事を書いた気がするw) すまんw 大嘘書いたww
>>998のコードだと trim() によって string型にキャストされるから永久ループするわwww
while (($input = fgets(STDIN)) !== false) {
echo $input;
}
が正しいが場合によっては
while (($input = trim(fgets(STDIN))) !== '') {
echo $input;
}
が期待した動作なのかもしれない 10011001Over 1000Thread
このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 342日 23時間 9分 23秒
10021002Over 1000Thread
5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。
───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────
会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。
▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/
▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php