投稿

ラベル(PHP)が付いた投稿を表示しています

mysqli から View を select しても結果が得られない

PHP で mysqli ( prepare )を使用して、SELECTにビューを指定したが、結果が得られなかった さくらのレンタルサーバ上 mysql 5.7, php 8.0.30 phpMyAdmin からは表示可能(ビューをそこで作成したからね) テーブルと単純なビューを作成して確認 → ビューのみ結果が得られない mysql側の権限を疑ったが、レンタルサーバにビューの詳細な設定はなし mysqli のオプションを確認するが、それっぽいのは見つからず 「mysqli view select not working」等で調べるとかなり古くから問題がある様子 PDOを使って解決 とか、そんな中  prepare 以外は動作する みたいな話を発見 確認したら PDO で確認 → OK mysqli::query  で確認 → OK mysqli + prepare + View という組み合わせがNGらしい 他を mysqli で作っていたので mysqli:query を使用することにしました ※インジェクション対策 mysqli_real_escape_string() で文字列のエスケープを忘れずに

PHP gmstrftime の代替

PHP 8.1.0 で 非推奨になったgmstrftime の代替 キャッシュの有効期限を header 関数で指定するのに使っていたため gmdate で書き換え フォーマットが違うので注意、特に%ヘッダが無いので GMT 等を含めると別の解釈をされます gmstrftime の フォーマット gmdate の フォーマット $cache = (60 * 60 * 24) * 1; // header('Expires: ' . gmstrftime('%a, %d %b %Y %H:%M:%S GMT', time() + $cache)); header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $cache) . ' GMT');

Pydio8 でファイルが表示されない→PHP 7.4が原因

イメージ
【2021/10/08 追記】 さくらの共有サーバでは、 2021/11/30 で PHP 7.3 の提供が終了 します(10/28 にPHP 7.4へ強制切り替え) NextCloudなどへの 乗り換え を検討しましょう さくらの共有サーバに設置した Pydio8 でファイルが表示できない不具合が発生 ログを調べると get_magic_quotes_gpc() に関連するエラー PHP7.4から非推奨だそうです さくらのコンパネから PHPを 7.3 以前へ戻す ※後日、さくらインターネットから予告なしにPHP7.4へ切り替えたとのメールあり

PHP7.2 で Warning: Use of undefined constant On - assumed 'On' な警告

PHPを7.2に上げたところ「 Warning : Use of undefined constant On - assumed 'On' (this will throw an Error in a future version of PHP) in 」 な警告 エラー表示をするために ini_set("display_errors", On); と書いていたが ini_set("display_errors", '1'); のように記述しなければならないらしい

さくらレンタルサーバのphpでUDPを送信しようとしたら socket_create が使えなかったので fsockopen を利用

さくらレンタルサーバのphpでUDPを送信しようとしたら socket_create が使えなかったので fsockopen を利用して UDPを送信 function UdpSender($host, $port, $msg){ /* $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); socket_sendto($sock, $msg, strlen($msg), 0, $host, $port); socket_close($sock); */ $fsock = fsockopen("udp://{$host}", $port); if($fsock){ fwrite($fsock, $msg); fclose($fsock); } }

php で未定義の配列に追加してもエラーが出ない方法

php で array() が未定義な変数に配列を追加してもエラーが出ない方法 $foo [host1]     [0]email1     [2]email2     [3]email3 [host2]     [0]email4     [2]email5     [3]email6 みたいな、連想配列に配列を含むような形 で、配列かどうか確認せずに email を追加していきたい つまり $foo[$host] が配列でなくても、警告無く追加していける方法 $foo[$host] += $email; // NG - インデックスがないぜ array_push($foo[$host], $email); // NG - array_push は 第一引き数は array でないとね $foo[$host][] = $email; // OK ということで [] であれば未定義でも、追加(配列に)可能

javascript の split で limit を指定すると limit以降が失われる → 仕様でした

javascript split の第2引き数 limit は、 「分割がlimitに達するか、limit未満で全て分割が終わるまで、分割する」 てことで、php なんかの limit まで分割して、最後の配列には残りすべてが入る とは意味が違います s = 'aaa,bbb,ccc'; s.split(',', 2) ====> Array('aaa', 'bbb'); // javascript split(',', s, 2) ====> Array('aaa', 'bbb,ccc'); // php

PHP の PDO で debugDumpParams の出力をファイルなどに保存

SQL の実行結果を確認しようにも bindValue や bindParam を使っていると、実行内容を取得できない debugDumpParams を利用すると SQL へ渡った情報を標準出力に吐き出すことが出来る その内容をファイルなどに保存する $stmt -> execute (); if ( ob_start ( 'callback' ) ){      try {          $stmt -> debugDumpParams ();     } finally {          // ob_end_flush();          ob_end_clean (); // callback からの戻り値を出力しない     } } function callback ( $buffer ){      file_put_contents ( 'sqlresult.txt' , $buffer );      return $buffer ; } 通常は execute() の直後に debugDumpParams() を呼び出せば、標準出力に吐き出されますが ob_start(関数名) で、内容をコールバック関数へ渡しています。今回は 標準出力へ表示する必要が無いので、ob_end_clean() を用いていますが、callback の戻り値を出力する場合は ob_end_flush() を利用します。 $stmt -> execute (); if ( ob_start ( 'callback' ) ){      try {        ...

PHP の call_user_func_array + bind_param で参照渡し

call_user_func_array で mysqli の bind_param を呼び出しをまとめつつ、汎用性をもたせたい bind_param は 第2引き数以降が参照渡しでなければならないので、渡す配列を作成する段階で参照渡しを入れておく必要があるが、毎回面倒なので配列を再生成することで落ち着く // 警告が出るパターン // Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a reference, value given in $params = array ( 'i' , 2 ); call_user_func_array ( array ( $stmt , 'bind_param' ), $params ); // 引き数を意識するパターン $id = 2 ; $params = array (); $params [] = 'i' ; $params [] = & $id ; // パラメータは参照渡し call_user_func_array ( array ( $stmt , 'bind_param' ), $params ); // お手軽なパターン $params = array ( 'i' , 2 ); for ( $i = 1 ; $i < count ( $params ); $i ++){ // 2番目以降を参照渡しに書き換え      $params [ $i ] = & $params [ $i ]; } call_user_func_array ( array ( $stmt , 'bind_param' ), $params ); ここで $params を作成する時に foreach($data as $key => $value){ $params[] = &$value } の様に行ってはいけません 上記は $value 参照を代入することになり、次のループで $value が書き換えられ、結果的に配列の最後の値を全てが参照することになります for...

UniServer Zero で sqlite が使えない

イメージ
UniServer Zero ZIII で sqlite が使えない → php の sqlite エクステンションが有効になっていない 使用している php.iniを調べるため phpinfoを表示させる 使用している php.ini を確認→エディタで開く sqlite を検索して、利用したい extension (今回は pdo) のコメントアウトを削除 Apacheを再起動する

Google Home の独自コマンドを PHP から応答

イメージ
Google Home(Assistant) の独自コマンドを PHP(Webサーバ) から応答させたときのメモ 【注意】 ここで使用する独自コマンドは、Google Home から独自コマンドが搭載された自作アプリへ接続して、会話を行うような利用方法です。ok,google に続いて一発ものの命令を行う場合 IFTTT を利用するほうが容易です 基本的な流れは こちら を参考にさせていただきました 上記は例が python + Flask なので既存のサーバへ受け渡すのとはちょっと違ったのでPHPの場合を捕捉 大まかな流れ等 DialogFlow のアカウントを有効にするGoogleサインアップがフツーかもGoogle傘下なので Agentを作成(この中に intent を複数作成していく) Intentを作成(音声命令 = intent な感じです) 解説に有る Fulfillment のチェックボックスが見つからないのは、Fulfillment が定義されていないからです。Fulfillmentを定義すると出現します Entities は音声命令を節毎に分離して汎用性を高められます 「 テレビ の 電源   入れて 」の各節を TV とか パワー とか オンして  みたいなゆらぎを入れてクロスでマッチしてくれたりします(後で intent に組み込めるのでテストでは飛ばしてもOK) Fulfillment で呼び出す URLを指定 ここのURLは Agentと対になり Intent の Action が送られてきますので、URLが違えば Agent も違うという事になる Intent が音声等で選択されると Fulfillment で指定されたURLへ json形式のデータが送られてきて、レスポンスも json形式で返すことになります PHP の場合、 こちら の 形式で応答(Action の sayHello が該当の箇所) また、送られてくる json は、DialogFlowの右側にある「try it now」からコマンドを入力して、一番下の show json で確認できるので、ファイルに保存して 上の $update_response = file_get_contents ...

maildrop の .mailfilter でスクリプト実行の種類

イメージ
maildrop の .mailfilter で スクリプト(今回は php) 実行させた時のメモ さくらのレンタルサーバーのメールで、独自のフィルタを作成するにあたって、php の実行方法(2種類)による動作の違い xfilter で php スクリプトを呼び出した場合 .mailfilter xfilter "/usr/local/bin/php /home/HOHOHO/www/FUFUFU/test.php" if ($RETURNCODE == 1) { to "maildir/.Trash/" } test.php <?php $data = file_get_contents("php://stdin"); file_put_contents("php://stdout", $data); // exit(1); return 1; ?> 結果 php で return 1; も exit(1); も $RETURNCODE へ値が反映されない(常に0) stdout を行わないとメールが消失する(stdin → stdout をセットで利用) echoで出力してもok stdout で出力した結果(メールソース)がその後利用される → ヘッダに結果を残すなど exit(1); を使うと stdout が動作していない様子 → メールが消失する シングルクォーテーション(&H60) で php スクリプトを呼び出した場合 .mailfilter `/usr/local/bin/php /home/HOHOHO/www/FUFUFU/test.php` if ($RETURNCODE == 1) { to "maildir/.Trash/" } test.php <?php $data = file_get_contents("php://stdin"); // file_put_contents("php://stdout", $data); exit(1); ?> 結果 php で return 1; は ...

pear net_imap connect で "already connected, logout first!" のエラー

$imap = new Net_IMAP(); if( PEAR::isError($ret = $imap->connect('hostname', 993)) ){ echo $ret->getMessage(); // "already connected, logout first!" } のように、connectで既に接続済みのエラーが出る Net_IMAP のコンストラクタは Net_IMAP('localhost' ... ) のデフォルト値を持っているので 実行サーバが IMAPを兼用している環境(レンタルサーバなど)では、コンストラクタの時点で、localhostへ接続してしまっている connect を使わず、コンストラクタでホスト指定→接続とする