かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

PHP json_decode がnullになるにハマる

PHPjson_decodeは値が " (ダブルコーテーションで)囲まれていないと null になるっぽい。

json_decode() でnull になるJSONのパターン

1. " で囲われていない値がある

json = {1: "星宮いちご"}
<?php
json_decode( json ); // => NULL

2. 値が ' (シングルコーテーション)で囲まれている

json = {"1": '<b class="idol">星宮いちご</b>'}
<?php
json_decode( json ); // => NULL

` ←コレもダメ

json = {"1": `星宮いちご`}
<?php
json_decode( json ); // => NULL

3. 行末に , がある

json = {"1": "星宮いちご",}
<?php
json_decode( json ); // => NULL

すべてのキーと値が " で囲まれていて、最後に不要な , もない場合ならOK

json = '{"1": "星宮いちご"}';
<?php
json_decode( json );
// => object  { ["1"]=> string(15) "星宮いちご" }
json_decode( json, true );
// => array(1) { [1]=> string(15) "星宮いちご" }

"で囲まれた値の中で'が使われているのはOK。
例えばHTMLタグを入れるような場合、値となる文字列は " で囲み、属性は'で囲めば大丈夫

json = ["<b class='idol'>星宮いちご</b>", "霧矢あおい", "紫吹蘭"];
<?php
json_decode( json );
// => array(3)  { [0]=> string(35) "<b class='idol'>星宮いちご</b>" [1]=> string(15) "霧矢あおい" [2]=> string(9) "紫吹蘭" }
json_decode( json, true );
// => array(3)  { [0]=> string(35) "<b class='idol'>星宮いちご</b>" [1]=> string(15) "霧矢あおい" [2]=> string(9) "紫吹蘭" }

PHP上の文字列でJSONを作る場合は全体を'で囲むか、値を囲む"エスケープすればOK (最初からObjectや配列作れば良くね?需要あるのか謎だけど...)

<?php
$json = '{"みくるの": "みらくる!"}';
json_decode( $json );
// => object  { ["みくるの"]=> string(15) "ミラクル!" }
$json = "{\"みくるの\": \"ミラクル!\"}";
json_decode( $json );
// => object  { ["みくるの"]=> string(15) "ミラクル!" }

 
javascriptだと問題ないようなjsonPHPjson_decode()だとnull になって少しハマりました。
PHPのバージョンが上がって解消されるといいな...


[参考]

Gulp gulp-uglify でmin化しようとしたらエラーになった件

Gulpでjsをminfy化しようとしたら、次のようなエラーが表示されるようになってしまいました。

[21:34:54] Starting 'uglify'...
events.js:160
      throw er; // Unhandled 'error' event
      ^
GulpUglifyError: unable to minify JavaScript
...

uglify のタスクは昔作ってたものの使い回しでこんな感じ

var uglify = require("gulp-uglify");
var rename = require('gulp-rename');

gulp.task('uglify', function(cb) {
  return gulp.src( src )
    .pipr( uglify({
      // ! から始まるコメントを残すオプションを追加
      preserveComments: 'some'
    }) )
    .pipe( rename({
      extname: '.min.js'
    }) )
    .pipe( gulp.dest( assetDir ) );
});

何がエラーなのか調べる

表示されているエラーから何が原因なのかイマイチ解らなかったので、下記のようにuglifyに.on('error')を付けてエラーを表示してみました。

gulp.task('uglify', function(cb) {
  return gulp.src( src )
    .pipr( uglify({
      // ! から始まるコメントを残すオプションを追加
      preserveComments: 'some'
    })
    .on('error', function(e){
      console.log(e);
    }) )
    .pipe( rename({
      extname: '.min.js'
    }) )
    .pipe( gulp.dest( assetDir ) );
});

↓ 表示されたエラーの中に次のように表示されていました。

[21:34:54] Starting 'uglify'...
# 中略
message: '`preserveComments` is not a supported option',

どうやら!から始まるライセンスのコメントを残すオプションのサポートが無くなっているようです。

gulp-uglify v3.0.0 から preserveComments オプションは使えない

どうやらgulp-uglify v3.0.0 からはUglifyJS2に合わせてライセンスのコメントを残す方法が変更になっており
新規プロジェクトでnpm updateした際にgulp-uglifyのバージョンが上がり無効なオプションになってしまっていたのが原因だったようです。

gulp-uglify v3.0.0 で /*!, //! で始まるコメントを残す方法 に書き換えればOKでした。

Output options

👇

gulp.task('uglify', function(cb) {
  return gulp.src( src )
    .pipr( uglify({
      output:{
        comments: /^!/
      }
    })
    .pipe( rename({
      extname: '.min.js'
    }) )
    .pipe( gulp.dest( assetDir ) );
});

その他のオプションの指定方法は UglifyJS2 のGitHubページに載っています。
 
node系はしれっとアップデートの際に後方互換無しの変更されていたりするのでパッケージをアップデートするときとかは特に注意が必要ですね。デザイナーさんやコーダーさんでエンジニアにgulpを使って言われたままに黒い画面でnpm installしたけど上手く動かない!とか結構ありそう…


[参考]

↑ gulp-uglify v2.0.0 の書き方だったので修正しました。

PHP 文字列末にある特定の文字を除去したい。

例えば WordPressを使ったサイトで home_url('/') でサイトのURLを取得してそこからURLを組み立てたい時とか。
home_url('/') は行末に / が出力されるので、/ 始まりの変数と結合するとイケてないURLに…

<?php
define('IMG_DIR', '/assets/images');
$dir = home_url('/') . IMG_DIR;
echo $dir;
// => http://example.wordpress.com//assets/images

str_replace() を使って削除できるけど正規表現が必要なので、そこまでカロリーを使いたくない…

trim系の関数で除去できた!

trim系の関数は第二引数に除去する文字列を指定することができるようです。
これを利用して、行末の/を除去したい場合は rtrim(str, '/') とすればOK。

rtrim
string rtrim ( string $str [, string $character_mask ] )
パラメータ
character_mask 削除する文字を指定することも可能です。 削除したい全ての文字をリストにしてください。.. を文字の範囲を指定する際に使用可能です。
出典: PHP: rtrim - Manual

<?php
rtrim( home_url('/'), '/' ); // => http://example.wordpress.com

echo rtrim( home_url('/'), '/' ) . IMG_DIR;
// => http://example.wordpress.com/assets/images

簡単にできた(۶•̀ᴗ•́)۶

trim() って空文字除去ってイメージしかなかったので、第二引数で除去する文字列を自由に指定できることは知りませんでした… (そういえば行末の改行削除とかでも使ってた気がしてきた…
確かにtrimって刈り込むとか切り落とすとかって意味ですから、空文字に限らなくても不思議ではないですね!


[参考]