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の改造
0052nobodyさん
2016/10/18(火) 18:53:15.51ID:???そしてそれを IN が使えないという話にしてはいけないということ。
それ以外の話で IN が使えないというのなら、使えないって人からの追加説明が必要かなと。
0053nobodyさん
2016/10/18(火) 18:54:24.93ID:???$stmt->bindValue(':query', 'select * from foo where bar="baz"', PDO::PARAM_STR);
これがバインド出来ねーって言ってるようなもんだろ
0055nobodyさん
2016/10/18(火) 22:51:36.87ID:???{
foreach($b as $value).... // bを配列として変換済み
}
上の関数を呼び出す時に、下記のようにbをarrayでもintでも可能にしたいです。
testfunc(a, [1,2,3]);
testfunc(a, 1);
どういう風に関数実装すればよいでしょうか
0056nobodyさん
2016/10/18(火) 23:48:00.25ID:???bを配列として何らかの変換を行っているのであれば
条件分けでもいけるのでは?
もしくは引数を配列にするとか
0058nobodyさん
2016/10/19(水) 00:05:25.02ID:???無理筋じゃーねーよ。他の言語のデータベース接続インターフェースとかじゃ割と出来るし、PDOを拡張するだけで一応は実装可能なんだから。
PDOが名前付きプレースホルダ自体に配列が使えないっつーワンサイドハンドドロップダウン仕様なのが問題なんじゃ。
0059nobodyさん
2016/10/19(水) 00:18:28.66ID:???>>49を読んで, その上でそう思うということなのか?
あと, SQLを抽象化しないDBALで"出来る"例を挙げてくれ
0060nobodyさん
2016/10/19(水) 00:28:41.03ID:???知らんけど、同じくDBALを謳う「PDOを拡張したクラス」が山のようにある(そしてそいつらは配列をバインドできる)のはどういうことや?
PDOはRDBMSの種類毎の違いを抽象化してくれてるまではええんやが、プリペアードステートメントのパラメータのバインド部分が貧弱なんだよ。だからみんな拡張するんだ。
ドキュメントにも書いてある通り、「端的に言えば文字列置換してるだけやで」って位だからな。気が利かない。
0061nobodyさん
2016/10/19(水) 00:29:17.31ID:???0062nobodyさん
2016/10/19(水) 00:29:57.71ID:???0063nobodyさん
2016/10/19(水) 00:31:09.84ID:???0064nobodyさん
2016/10/19(水) 00:33:33.91ID:???つうかみんなそこら辺に不満言いながら拡張PDO書くのがphpおじさんたちの仕事だよ。
もっと言うならexecuteした後にfetchさせるのとかもクッソ面倒いから大体そこも拡張っつーかラップするよ。
0065nobodyさん
2016/10/19(水) 00:40:40.11ID:???プリペアドステートメントのバインドが文字列置換だけなわけがない
通常のいわゆる静的プレースホルダではDB側が用意した(PREPARE文で発行した)ステートメントにUSING句でバインドして実行している
DB側でこの機構に対応していない場合(や利用しようとして失敗した場合(今はどうか知らない))にはエミュレーション(いわゆる動的プレースホルダ)としてPHP側が処理を代替する
静的プレースホルダの機能はDB側機能で制約を受ける
PDOは"SQLを抽象化しない""DBへの接続とクエリのみを抽象化する"DBALである以上, SQLを弄らねばならない機能はより上位のレイヤで実装されなければならない
006665
2016/10/19(水) 00:43:28.22ID:???0067nobodyさん
2016/10/19(水) 00:56:34.77ID:???つうても静的プレースホルダに配列を突っ込めるRDBMSは多分存在するよな?
なんで、in句にプレースホルダを入れてそこに配列バインド出来ないのはやっぱりPDO側の怠慢やと思うんや。
エミュモード有効なら結局SQL組み直すやん。
なら配列入れて無効なら展開するような仕様でええ思うんだけどな。(まあ、その仕様入れるとSQL自体がバグる可能性もあるので一長一短だが)
006865
2016/10/19(水) 01:07:02.59ID:???> つうても静的プレースホルダに配列を突っ込めるRDBMSは多分存在するよな?
知る限りないが, ご存知なら挙げてくれ
> エミュモード有効なら結局SQL組み直すやん
プリペアドステートメントが利用可能かどうか結果が変わる仕様はまともではない
少なくともプリペアドステートメントという以上はDBのそれと1対1であるように実装されるべきだし, そうなっている
何度も言うようだけどもその枠から外れるならそれはPDOが目指すものではない
0069nobodyさん
2016/10/19(水) 01:15:52.87ID:???ワイも詳しくないけど、なんかオラクル辺りは配列バインド出来るらしいよ。ODP.netにはそういう機能があるらしい。
それがSQLを破壊してるかどうかまでは分からんけど。
007065
2016/10/19(水) 01:19:10.84ID:???その「配列をバインド出来る」の意味は :array というプレースホルダにARRAY型の値をそのまま置き換えるということだろう
決して :array にバインドするARRAY型変数の中身が展開されて並ぶわけではない
ましてやIN句には括弧が必須なのだから IN :array みたいな書き方をすればコンパイルエラーだ
0071nobodyさん
2016/10/19(水) 01:25:15.44ID:???何言ってるか微妙に分からんが、SQL上で
in(1,2,3,4,5)みたいになっているのは、php上で[1,2,3,4,5]になってるのとは等価だろ。
データの内部形式に違いはあれど配列を扱っていること自体に違いはない。
その配列形式のデータをDB側が受け取れるかどうかじゃねえか。
もっと具体的に言うとmysqlにはSET型もenum型もあるんやから、コレをPDO側で吸収する事は本来は出来るハズやで。postgresにはpolygonとかもあるやん。
ここら辺のデータを受け渡すインターフェースがあってもおかしかないとは思うんやがのう。
0073nobodyさん
2016/10/19(水) 01:30:23.68ID:???0075nobodyさん
2016/10/19(水) 02:23:17.81ID:???IN文の中身に関してはそうだけど、values()の中身とかは実質配列型だろ。
だから配列をぶっこむプリペアードステートメントが存在しても全然おかしくないしmysqlはSET型ぶち込めるし。
やっぱPDOが手を抜いてる説がワイの中で根強いなあ。
0076nobodyさん
2016/10/19(水) 02:27:05.66ID:???0077nobodyさん
2016/10/19(水) 02:28:37.37ID:???プリペアードステートメントだから配列は使えないなんてのはすげえ雑な扱いに思うけどね。
いくらPDOがネイティブ寄りの思想だからって出来ないこと多すぎなんやが。
0078nobodyさん
2016/10/19(水) 02:32:17.19ID:???実質配列型というが, SQLのARRAY型の要素は全て同じ型だ
「だから配列をぶっこむプリペアードステートメントが存在しても全然おかしくない」というのもSQL文との整合性が保たれない(IN句で IN :array は認められない)以上はプリペアドステートメント「のようなもの」ではあってもそのものではない
まるでPDOに特有の問題かのように言うが, 理想的, 或いはPDOよりマシだという実装の具体例を(別の言語でも結構だが)挙げてくれないと比較のしようもない
0079nobodyさん
2016/10/19(水) 02:32:28.64ID:???$st->bind(":in","SELECT 1,2,3")とかやればいいような気がしてきたな。
それもそれで面倒な気もするが。
0080nobodyさん
2016/10/19(水) 02:49:33.98ID:???回答はやはりPDOより上のレイヤーでやるべきだと
https://bugs.php.net/bug.php?id=64852
0081nobodyさん
2016/10/19(水) 02:53:25.31ID:???INは実行前に数がわからない。だから「何なら入れていいか」がわからない。
が、values()とかは数も型もわかる。
数と型が分かるなら、それこそ文字列と同じ扱いにできるやな。
実際にJavaのPreparedStatementクラスにはSetArray()ってメソッドがあるらしいぞ。
使ったことないからどれくらい使えるかわからんが。
0082nobodyさん
2016/10/19(水) 03:02:36.73ID:???> 数と型が分かるなら、それこそ文字列と同じ扱いにできるやな。
VALUES(?, ?, ?)などとしてPHP配列を要素を適切に並べてバインドすればよいとういことか?
最早元の話題から大きく外れているが, どういうAPIで実装すべきと考えているのか
JavaのSetArrayは正しくSQL文中のプレースホルダをARRAY型の値で置き換える
相当するものはPDOにはないからあってもよいとは思うが, IN句やVALUESで指摘された問題の解決にはなっていない(その目的には使えない)
0083nobodyさん
2016/10/19(水) 03:09:34.66ID:???0084nobodyさん
2016/10/19(水) 03:21:09.25ID:???>ここら辺のデータを受け渡すインターフェースがあってもおかしかないとは思うんやがのう。
PDOにしろADO.NETにしろJDBC、ODBC、ADO,OLEDBにしろ、基本はデータベースをベンダによらず
抽象的に扱えるインタフェースを提供するのが目的なんだから、特定のデータベースの特定の
型向けのインターフェースなんて用意しないだろ。
0085nobodyさん
2016/10/19(水) 03:27:06.04ID:???TEXTだったりvarcharだったりをSTRINGに抽象化する程度には纏められるやろ。SET型もpolygon型も実態は固定長の配列やし。それこそarrayで一纏めに出来るはずやで。
0086nobodyさん
2016/10/19(水) 03:27:34.58ID:???具体的に例あげろよ。
0087nobodyさん
2016/10/19(水) 03:29:00.07ID:???そういうのはもう設計してる人に言おうぜ。俺らに
何度言ったって無駄だろ??
それともただのかまってちゃんなの?
0088nobodyさん
2016/10/19(水) 03:30:26.87ID:???0089nobodyさん
2016/10/19(水) 03:30:40.03ID:???ただのかまってちゃんレベルになってきてるぞ。
0092nobodyさん
2016/10/19(水) 03:48:00.91ID:???クエリビルダじゃなくてデータベース接続インターフェースって自分で言ってないか?
話が変わってねぇ?
0093nobodyさん
2016/10/19(水) 04:51:13.91ID:???0094nobodyさん
2016/10/19(水) 06:22:40.53ID:???foreachで楽に組み立てられるだろ
0096nobodyさん
2016/10/19(水) 10:30:47.12ID:???PostgreSQLだと、INの方が速いけどね。
10万件の中から10件を検索(indexが使われる検索)
INを使った場合:
https://explain.depesz.com/s/PpNF
Planning time: 0.141 ms
Execution time: 0.177 ms
ORを使った場合:
https://explain.depesz.com/s/iORg
Planning time: 0.281 ms
Execution time: 0.469 ms
0097nobodyさん
2016/10/19(水) 10:31:49.79ID:???0098nobodyさん
2016/10/19(水) 10:43:30.73ID:???日本在住じゃないのか?
0102nobodyさん
2016/10/19(水) 14:06:53.65ID:???安全のためにね
↓
プリペアードクエリ使え
↓
IN句じゃつかえないだろ
↓
いや使えるし
↓
でもコードを少し書かないと使えないだろ
その意味で使えないと言ったんだよ
そもそもIN句遅いし、OR使えよ
↓
いやIN句の方が速いし
↓
今ココ
0103nobodyさん
2016/10/19(水) 14:14:37.64ID:???PDOはDBへの接続を抽象化するためのものでSQLを抽象化するためのものではない
なぜ全てをPDOに要求するのか?
0104nobodyさん
2016/10/19(水) 14:18:54.42ID:???{
$array = [];
foreach ($variable as $value) {
$array[$value] => [1,2,3];
}
return $array;
}
こういうのって最初に
$array = [];
で初期化する必要ないのかな?
削除するかで迷ってる
0105nobodyさん
2016/10/19(水) 14:19:11.56ID:???0108nobodyさん
2016/10/19(水) 14:37:40.79ID:???> 俺は多分カニ味噌?と言われた人間だが別の人とやり合ってたようだなw
かに味噌がどうこうという流れは無視してたが、最近の流れを追うとそう言われるのも妥当かなと思ったりw
0110nobodyさん
2016/10/19(水) 15:52:44.73ID:???PHPを主体にしてやってるんでしょうか?
0111nobodyさん
2016/10/19(水) 17:11:58.32ID:???0112nobodyさん
2016/10/19(水) 17:12:37.66ID:???0113nobodyさん
2016/10/19(水) 17:17:09.08ID:???柔軟にいろいろ吸収できれば何とかなると思うけど。
0115nobodyさん
2016/10/19(水) 17:25:51.43ID:???0116nobodyさん
2016/10/19(水) 17:34:13.99ID:???> だから配列をぶっこむプリペアードステートメントが存在しても全然おかしくないし
これには同意
$stmt = $pdo->prepare('select * from user where created between ? and ? and status in (?)');
$stmt->execute([$from, $to, ['hoge', 'fuga']]);
って書かしてくれてもばちはあたらんと思うぞ
0118nobodyさん
2016/10/19(水) 18:07:48.96ID:???arrayBind
arrayExecute
とかね
0119nobodyさん
2016/10/19(水) 18:18:24.40ID:???問題ない。
$sql = 'insert into books (tilte, authors) values (?, array[?])';
$stmt->execute(['php is sucks', ['matz', 'larry']);
$array = ['matz', 'larry'];
$stmt->execute(['rtfm', $array]);
0120119
2016/10/19(水) 18:20:48.34ID:???0121nobodyさん
2016/10/19(水) 18:51:55.67ID:???phpはあくまでサーバサイドのコードやからコンマ何秒を求められる事はこれから先も無いよ。
マキシマム数秒は大前提だけど、マキシマム何秒に抑えるのはphpとかの言語を駆使する話ではない。
システム構成とそのアプリケーションの仕様との相談だね。
0122nobodyさん
2016/10/19(水) 18:52:03.03ID:???0123nobodyさん
2016/10/19(水) 18:55:43.49ID:???PDOより上の機能をphp標準が用意してくれないからだろ……
だから名前も分からぬ機能もインターフェースも雑多なr/oマッパーが蔓延るんやないかい。
ワイらはORMなんか別に使う気はなく、クエリを安全にエスケープできればええゆうのに。
0124nobodyさん
2016/10/19(水) 18:56:11.91ID:???そんなもんしかないからな
0127nobodyさん
2016/10/19(水) 19:18:34.73ID:???0128nobodyさん
2016/10/19(水) 19:45:08.74ID:???いくつものjoinによっては可読性を落とし
MySQLのバージョンを理由に、謎のselect連発
だから、PDOなり、ORMなり、クエリービルダーなり、きちんと設計されて
使用されているところのほうが珍しい
0129nobodyさん
2016/10/19(水) 19:46:10.18ID:???実際にPDOを継承したり内包してるDBライブラリが数数え切れない程度にあるこの状況を見てどう思うね。
もうちょい統一してほしい思うやろ。
0131nobodyさん
2016/10/19(水) 19:50:13.31ID:???PDOに持たせなくてもいいから、PDOより上でORMより下くらいの扱いやすいDB操作インターフェース作れや。
今のopenGL直に叩いてるような状況が正しい訳ねえやろ。
0132nobodyさん
2016/10/19(水) 19:50:14.37ID:???0133nobodyさん
2016/10/19(水) 20:15:41.19ID:???一体どんな言語が, 言語の規格に存在しないにも拘らずDB接続の抽象化を超えるような機能をその言語ベンダ自身で提供しているんだ?
その機能を提供するための標準的なAPIの規格でも存在しているのか?
クエリをどうこうしたいなら単にクエリビルダだけを使えばよい(illuminate/databaseのQueryBuilderだけでも使える)
大体ORMレベルまで行ってしまったらActiveRecordとDataModelみたいな設計方針の違いもあるんだから多様性はあって当然
言語ベンダとしては最低限, DBへの接続を抽象化する, その目的はPDOで適切に達成されている
0134nobodyさん
2016/10/19(水) 20:21:05.62ID:???APIは提供したからあとは描画するだけだよ、頑張ってね的なほっぽり投げ具合だから嫌だっつってんだろ。
openGLやってバージョン上がるごとにどんどん抽象化レベル高くなってんねんで。
PDOがそこやってもええやろ。
そもそもプリペアードクエリの?文字も:文字もDBの仕様じゃないのをPDOが拡大解釈しとる話やん。
もっと制御文字増やして拡大解釈しまくるくらいは出来るやろ?
0135nobodyさん
2016/10/19(水) 20:26:01.53ID:???0137nobodyさん
2016/10/19(水) 20:27:48.58ID:???0138nobodyさん
2016/10/19(水) 20:28:15.02ID:???0139nobodyさん
2016/10/19(水) 20:30:38.82ID:???ああ言えばこう言う、でもでもだって
0140nobodyさん
2016/10/19(水) 20:31:18.78ID:???0141nobodyさん
2016/10/19(水) 20:31:29.20ID:???そういうご要望はPHPの公式メーリングリストにでも投げられたら如何か
EloquentもDoctrineもある現状, どの程度合意を得られるかは分からんが, 納得させるのが上手いプレゼンターだ
0142nobodyさん
2016/10/19(水) 20:33:09.84ID:???と思うじゃん? sqliteとか普通にプリペアードステートメントの機能が無いDBもあるじゃん?
そういうRDBMSからすればクエリを破壊してる事にはなってるわけじゃん?
0144nobodyさん
2016/10/19(水) 20:36:24.67ID:???0145nobodyさん
2016/10/19(水) 20:38:30.76ID:???それってつまりはPDOがDBの仕様(というかインターフェース)を決めている事に他ならん訳でな。
「他のDBには無いけどPDOがエミュレートしてくれる」なら周りを気にせずどんどん抽象化できるやん?
0146nobodyさん
2016/10/19(水) 20:42:51.81ID:???0147nobodyさん
2016/10/19(水) 20:43:30.59ID:???"DBに委任出来ることは委任する"のが前提
まぁ, 納得してもらわなくていいけど, 「俺の欲しい機能が公式で実装されてない」という主張, そしてそれを実装しろという要望は, ここよりPHPの公式でぶちまけるべきだ
そしてうまいこと公式の開発者たちを説得してくれ, PDOより上のレイヤは実装されている分には構わんからな
0148nobodyさん
2016/10/19(水) 20:47:59.42ID:???sqliteで思い出したけど、PDOってエミュレートどころか使えない機能を使っても使えたフリだけするパターン(トランザクションとか)がかなりあるで。
ミニマムスペックで汎用なように作ってるつもりでも実態は全然目標とは乖離してるがな!
やっぱPDOは勝手に拡張されていくべきだわ。PDOこそがDB操作の標準になるくらいがええ。
0149nobodyさん
2016/10/19(水) 20:53:09.97ID:???0150nobodyさん
2016/10/19(水) 20:57:21.52ID:???なにも汎用性重視のPDOにそんな要求しなくても
0151nobodyさん
2016/10/19(水) 21:00:08.08ID:???ベンダもそれぞれバージョンアップとかで新機能導入していくんやから、様子見てPDOがメインストリームになりそうなのを抽象化して実装するのが筋やろなあ。
0152nobodyさん
2016/10/19(水) 21:03:14.15ID:???ORMではなく。
phpがそれやってくれると普及すると思うんやけどなあ。
■ このスレッドは過去ログ倉庫に格納されています