PHPのhtmlspecialchars関数でエンコードしてもJavaScriptエラーが出る件 
2024/07/30 Tue.
例えば
<button type="button" onClick="kansu('{$htmlspecialchars}')">ボタン</button>
というのがあるとします。
PHPの htmlspecialchars() 関数で文字列をエンコードする際、
$htmlspecialchars = htmlspecialchars($mojiretsu, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5);
でエンコードしたらJavaScriptでエラーが出る。
なんでかなあ?といろいろ試した結果シングルクォートを「'」にエンコードしてもJavaScriptでエラーになるんですね。
なので、JavaScriptに渡す部分だけ別途以下のように書いて書きだしたらうまくいきました。
$htmlspecialchars = str_replace(array('\\', '\''), array('\\\\', '\\\''), htmlspecialchars($mojiretsu, ENT_COMPAT | ENT_HTML5));
<button type="button" onClick="kansu('{$htmlspecialchars}')">ボタン</button>
というのがあるとします。
PHPの htmlspecialchars() 関数で文字列をエンコードする際、
$htmlspecialchars = htmlspecialchars($mojiretsu, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5);
でエンコードしたらJavaScriptでエラーが出る。
なんでかなあ?といろいろ試した結果シングルクォートを「'」にエンコードしてもJavaScriptでエラーになるんですね。
なので、JavaScriptに渡す部分だけ別途以下のように書いて書きだしたらうまくいきました。
$htmlspecialchars = str_replace(array('\\', '\''), array('\\\\', '\\\''), htmlspecialchars($mojiretsu, ENT_COMPAT | ENT_HTML5));
category: PHP JavaScript
PHPのfopenやfile_get_contentsでSSL接続が出来たりできなかったりしたメモ 
2024/06/23 Sun.
とあるレンタルサーバーのPHPで
fopen('https://~', 'r');
とやったときに接続できるURL、できないURLがあったので「なんでかなあ」と悩んだのですが、レンタルサーバーのPHPが「SNI」をサポートしてないのが原因でした。
どうしようもないです。はい。
PHPのSNIについては
SSL コンテキストオプション
を参照ください。
SNIを簡単に説明すると、
SSL通信はHTTPヘッダーが暗号化されているので一つのIPで複数ドメイン・ホストを動かしているサーバーでは、どのドメイン・ホストに接続したいのか分かりません。なので名前ベースのバーチャルホストを使っているサーバーはSSL通信ができないのですがそれをできるようにするのがSNIの仕組み。
サーバーとクライアントの両方が対応している必要があります。一般的にクライアントはブラウザになりますが、今回の私の場合はPHPがクライアントとなるわけです。
fopen('https://~', 'r');
とやったときに接続できるURL、できないURLがあったので「なんでかなあ」と悩んだのですが、レンタルサーバーのPHPが「SNI」をサポートしてないのが原因でした。
どうしようもないです。はい。
PHPのSNIについては
SSL コンテキストオプション
を参照ください。
SNIを簡単に説明すると、
SSL通信はHTTPヘッダーが暗号化されているので一つのIPで複数ドメイン・ホストを動かしているサーバーでは、どのドメイン・ホストに接続したいのか分かりません。なので名前ベースのバーチャルホストを使っているサーバーはSSL通信ができないのですがそれをできるようにするのがSNIの仕組み。
サーバーとクライアントの両方が対応している必要があります。一般的にクライアントはブラウザになりますが、今回の私の場合はPHPがクライアントとなるわけです。
PHPのfile_get_contents()などでリファラを記載する方法 
2023/03/16 Thu.
リファラをどこに書けばいいんだっけ?となったので備忘録メモ。
stream_context_create(array(
'http' => array(
'user_agent' => 'ie',
'header' => array(
'Referer: https://test.test'
)
)
);
「header」の一部に書けばよかったのね。
stream_context_create(array(
'http' => array(
'user_agent' => 'ie',
'header' => array(
'Referer: https://test.test'
)
)
);
「header」の一部に書けばよかったのね。
category: PHP
JavaScript FetchでのJSON.parseエラーで悩んだ 
2021/02/07 Sun.
JavascriptのfetchでPHPと非同期通信処理を行う仕組みを作ってました。
この仕組み自体は今までも経験あるのですが、今回はどういうわけか、
JSON.parse: unexpected character at line 1 column 1 of the JSON data
というJavascriptのエラーが発生してその原因を探るのに無駄な時間を割いてしまいましたので備忘録。
結論を申しますと、PHPがJSONを書き出す前に余計なテキストを書き出していたのが原因です。
もちろん、真っ先にJSONの書き出しが怪しいと思いました。
それでPHPが書き出すJSONデータをメールで送信して中身を確認したのですが、全く問題が見つからず。
過去に作ったプログラムと比較したりして何が違うかバグ探しをしたけどわからず。
で、やけになってJavascriptのコードの
return response.json();
という箇所を
return response.text();
にして受信内容をconsole.log()で表示してみたらJSONデータの前に余計な文言が書き出されてました。
原因は、外部PHPファイルを読み込んでいるのですが、その読み込むPHPファイルがテスト環境用のもので、その中にテスト用のコメントを書き出す部分が入っていたのが原因でした。
このテスト用PHPファイルをAJAX非同期通信システムで利用するのが初めてだったので、そのようなコメント書き出しがあるなんてことに気が付きませんでした。
理由がわかれば「なんだそんなこと?」ということに限ってなかなかバグが見つからないものです。
とりあえず、非同期処理でJSONデータを受け取るときに
JSON.parse: unexpected character at line 1 column 1 of the JSON data
というエラーが出たときは必ず余計な文字が書き出されているので、それを確認しましょう。
この仕組み自体は今までも経験あるのですが、今回はどういうわけか、
JSON.parse: unexpected character at line 1 column 1 of the JSON data
というJavascriptのエラーが発生してその原因を探るのに無駄な時間を割いてしまいましたので備忘録。
結論を申しますと、PHPがJSONを書き出す前に余計なテキストを書き出していたのが原因です。
もちろん、真っ先にJSONの書き出しが怪しいと思いました。
それでPHPが書き出すJSONデータをメールで送信して中身を確認したのですが、全く問題が見つからず。
過去に作ったプログラムと比較したりして何が違うかバグ探しをしたけどわからず。
で、やけになってJavascriptのコードの
return response.json();
という箇所を
return response.text();
にして受信内容をconsole.log()で表示してみたらJSONデータの前に余計な文言が書き出されてました。
原因は、外部PHPファイルを読み込んでいるのですが、その読み込むPHPファイルがテスト環境用のもので、その中にテスト用のコメントを書き出す部分が入っていたのが原因でした。
このテスト用PHPファイルをAJAX非同期通信システムで利用するのが初めてだったので、そのようなコメント書き出しがあるなんてことに気が付きませんでした。
理由がわかれば「なんだそんなこと?」ということに限ってなかなかバグが見つからないものです。
とりあえず、非同期処理でJSONデータを受け取るときに
JSON.parse: unexpected character at line 1 column 1 of the JSON data
というエラーが出たときは必ず余計な文字が書き出されているので、それを確認しましょう。
category: PHP JavaScript
PHP7.4で動作テストしてたら大量の配列エラーがでる 
2020/10/03 Sat.
これが
Trying to access array offset on value of type null
大量に出る。
PHP7.4では「配列でない値を配列スタイルでアクセスした場合」に警告がでるようになったようです。
例えば
<?PHP
echo $a[1];
?>
このように何も定義されてない状態の変数に配列としてアクセスするとエラーが出るというわけです。
こういうの結構書いちゃってます・・・。
配列として使うつもりだがまだ配列として中身が入ってない場合もあるという変数に配列形式でアクセスするプログラム。結構書いてるねえ。
何らかの対策が必要だとは思いますが・・・、
エラー制御演算子で
<?PHP
echo @$a[1];
?>
ごまかしちゃうとか・・・
E_NOTICEを・・・
上記例のような未定義変数に配列アクセスする場合は「Null合体演算子(??)」できちんと処理するべきでしょうけど・・・
Trying to access array offset on value of type null
大量に出る。
PHP7.4では「配列でない値を配列スタイルでアクセスした場合」に警告がでるようになったようです。
例えば
<?PHP
echo $a[1];
?>
このように何も定義されてない状態の変数に配列としてアクセスするとエラーが出るというわけです。
こういうの結構書いちゃってます・・・。
配列として使うつもりだがまだ配列として中身が入ってない場合もあるという変数に配列形式でアクセスするプログラム。結構書いてるねえ。
何らかの対策が必要だとは思いますが・・・、
エラー制御演算子で
<?PHP
echo @$a[1];
?>
ごまかしちゃうとか・・・
E_NOTICEを・・・
上記例のような未定義変数に配列アクセスする場合は「Null合体演算子(??)」できちんと処理するべきでしょうけど・・・
category: PHP
透過指定のあるPNGをimagejpegで出力すると黒く塗りつぶされる 
2019/03/30 Sat.
256色以下のパレットカラーの場合のPNG画像に透過指定がある場合、サイズ変更しない場合はなにも考えず、
$im = imagecreatefrompng('256色透過.png');
header('Content-type: image/jpeg');
imagejpeg($im, NULL, 70);
で問題なく出力されます。
しかし、リサイズする場合はちょっと工夫しないとJPEG出力したときに透過部分が黒くなってしまいます。
特に、透過指定のあるフルカラーPNGの場合は、リサイズしなくても黒く塗りつぶされてしまいます。
試行錯誤した結果、透過部分を指定した色で塗りつぶすという方法で解決とする。
$imIn = imagecreatefrompng('透過指定のある.png');
$x = imagesx($imIn);
$y = imagesy($imIn);
$imOut = imagecreatetruecolor($x,$y);
#背景を白にする場合
imagefill($imOut, 0, 0, imagecolorallocate($imOut, 255, 255, 255));
imagecopyresampled($imOut,$imIn,0,0,0,0,$x,$y,$x,$y);
header('Content-type: image/jpeg');
imagejpeg($imOut, NULL, 70);
これで透過部分に任意の色がついた状態でJPEG出力されます。
$im = imagecreatefrompng('256色透過.png');
header('Content-type: image/jpeg');
imagejpeg($im, NULL, 70);
で問題なく出力されます。
しかし、リサイズする場合はちょっと工夫しないとJPEG出力したときに透過部分が黒くなってしまいます。
特に、透過指定のあるフルカラーPNGの場合は、リサイズしなくても黒く塗りつぶされてしまいます。
試行錯誤した結果、透過部分を指定した色で塗りつぶすという方法で解決とする。
$imIn = imagecreatefrompng('透過指定のある.png');
$x = imagesx($imIn);
$y = imagesy($imIn);
$imOut = imagecreatetruecolor($x,$y);
#背景を白にする場合
imagefill($imOut, 0, 0, imagecolorallocate($imOut, 255, 255, 255));
imagecopyresampled($imOut,$imIn,0,0,0,0,$x,$y,$x,$y);
header('Content-type: image/jpeg');
imagejpeg($imOut, NULL, 70);
これで透過部分に任意の色がついた状態でJPEG出力されます。
category: PHP
PHPでリサイズしたPNG画像の透過背景が真っ黒になる 
2019/03/17 Sun.
imagesavealpha()関数を使用すればOK。
$im = imagecreatefrompng('PNG画像ファイル名');
#imagesavealpha関数を使用するためには アルファブレンディングを無効にする必要がある
imagealphablending($im, false);
imagesavealpha($im, true);
imagepng($im);
$im = imagecreatefrompng('PNG画像ファイル名');
#imagesavealpha関数を使用するためには アルファブレンディングを無効にする必要がある
imagealphablending($im, false);
imagesavealpha($im, true);
imagepng($im);
category: PHP
PHPの文字列と数値の比較であせった パート2 
2016/11/05 Sat.
●判定例1
('AA' == '')
これは FALSE。
●判定例2
('AA' == false)
これは FALSE。
●判定例3
('AA' == 0)
これは TRUE。
なんだかなぁ。なんでなんだろうなぁ。
こちらも参考にどうぞ。
PHPの文字列と数値の比較であせった
('AA' == '')
これは FALSE。
●判定例2
('AA' == false)
これは FALSE。
●判定例3
('AA' == 0)
これは TRUE。
なんだかなぁ。なんでなんだろうなぁ。
こちらも参考にどうぞ。
PHPの文字列と数値の比較であせった
category: PHP
preg_replace_callback のコールバック関数に複数引数を指定したい 
2016/05/31 Tue.
PHPに「preg_replace_callback」という関数があります。
使い方は
preg_replace_callback(正規表現パターン, コールバック関数, 置換元文字列);
です。
正規表現に「([0-9]+)」みたいなグループ指定があり、その値を利用して作成された文字列で置換を行いたいときにとても便利です。
単純に正規表現マッチだけをコールバック関数で利用する場合は簡単で、
preg_replace_callback('/([0-9]{3})-([0-9]{4})/', function ($matches) { return sprintf('%03d%04d', $matches[1], $matches[2]); }, $strings);
こんな感じで使えます。
しかし、今回コールバック関数に複数引数を指定する方法で困っていろいろ試してみたので備忘録メモ。
使い方は
preg_replace_callback(正規表現パターン, コールバック関数, 置換元文字列);
です。
正規表現に「([0-9]+)」みたいなグループ指定があり、その値を利用して作成された文字列で置換を行いたいときにとても便利です。
単純に正規表現マッチだけをコールバック関数で利用する場合は簡単で、
preg_replace_callback('/([0-9]{3})-([0-9]{4})/', function ($matches) { return sprintf('%03d%04d', $matches[1], $matches[2]); }, $strings);
こんな感じで使えます。
しかし、今回コールバック関数に複数引数を指定する方法で困っていろいろ試してみたので備忘録メモ。
category: PHP