読者です 読者をやめる 読者になる 読者になる

俺が生きている可能性は高い

人生ガンバローン

DataURLから画像へ変換するときはヘッダに気をつけてください的な話

Webブラウザで撮影した写真をサーバにアップロードしたいときってありますよね。

そういうときは大体video要素とかcanvas要素とかをガリガリ使って静止画にして canvas.toDataUrl() ったものをajaxAPIへ送信すると思います。

サーバサイドでは、送信されてきたbase64encodedな画像をdecodeして煮るなり焼くなりすれば良いのですが、実際にはちょっと注意が必要です。

canvas.toDataUrl() の返り値

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAADElEQVQImWNgoBMAAABpAAFEI8ARAAAAAElFTkSuQmCC

ご覧の通り、純粋なbase64文字列ではなく、

  1. データURIスキームであること
  2. 画像の種類
  3. base64エンコードされていること

を示すヘッダがついてます。

この部分ですね

data:image/png;base64,

なので、 ボケーっと

$photo = base64decode($request->input('photo');

とかやると、壊れた画像が出来上がっちゃいます。

ちゃんとヘッダ部分を取り除いてからbase64decodeしましょう。

$offset = strpos($req->input('photo'), 'base64') + 7;
$base64encoded = substr($req->input('photo'), $offset);
$photo = base64_decode($base64encoded);

参考文献

  1. https://developer.mozilla.org/ja/docs/Web/API/HTMLCanvasElement/toDataURL

PHPでマジックメソッド __toString() 内で例外を投げるとfatalになる

php

学び: __toString()でexceptionをthrowするとfatalになる

php > print PHP_VERSION;
5.6.10
php > Class Foo { public function __toString() { throw new \RuntimeException(); }};
php > print (new Foo);
PHP Fatal error:  Method Foo::__toString() must not throw an exception in php shell code on line 0
PHP Stack trace:
PHP   1. {main}() php shell code:0

Fatal error: Method Foo::__toString() must not throw an exception in php shell code on line 0

Call Stack:
    7.3242     226288   1. {main}() php shell code:0

PHP7.0.3で検証しても同様だった

php > print PHP_VERSION;
7.0.3
php > Class Foo { public function __toString() { throw new \RuntimeException(); }};
php > print (new Foo);
PHP Fatal error:  Method Foo::__toString() must not throw an exception, caught RuntimeException:  in php shell code on line 0
PHP Stack trace:
PHP   1. {main}() php shell code:0

無名クラス使いたかっただけ

php > print PHP_VERSION;
7.0.3
php > print (new class { public function __toString(){ throw new RuntimeException(); }});
PHP Fatal error:  Method class@anonymous::__toString() must not throw an exception, caught RuntimeException:  in php shell code on line 0
PHP Stack trace:
PHP   1. {main}() php shell code:0

参考URL * http://qiita.com/Hiraku/items/195222c4f4f223e435fa * https://bugs.php.net/bug.php?id=53648

sudoをパスワード無しで使う

unix sudo

こんばんは、こんばんは

sudoしてますかーーーー?

unix系OSにはrootとして任意のコマンドを実行する sudo というコマンドがあります。 このコマンドはデフォルトだと wheel グループに所属しているユーザのみ利用可能ですが、それ以外のユーザでも使いたいケースがあると思います。

そういう時には visudo コマンドで表示されるfileに下記のように追記すればOKです。 ちなみに、みんな大好きviでfileは開かれるので初めての人、苦手な人は気をつけて下さい(?)

some-user ALL=(ALL)     ALL

上記の意味は、ざっくり言うと「some-userユーザに対して、すべてのコマンドに対してsudoを許可する」です。

この時、some-userユーザにパスワードが設定されている場合、そのユーザのログイン後最初のsudo時にパスワードが要求されます。 どうしてもパスワードを要求されるのがアレだわーみたいな時はNOPASSWDオプションを指定してあげれば要求されません。

some-user ALL=(ALL)     NOPASSWD: ALL

で、 ここまでは「あっ、はい。」って感じだと思うのですが、

実は今日気づきがあって、こんな感じのsudoersで、some-userユーザがwheelグループに属している場合、some-userユーザのsudoコマンド実行時に パスワードが要求される んですね!

some-user ALL=(ALL)     NOPASSWD: ALL
%wheel  ALL=(ALL)       ALL

some-userについての記述がwheelグループについての記述より後の場合は、パスワードが要求されませんでした。 なので、ユーザレベルでの設定よりもグループレベルでの設定の方が優先される、とかではなくて、単純にそのユーザに対して適用されるルールをオーバーライドしていくロジックっぽいですね。

余談

visudoの実体としては /etc/sudoersvimで開いて、saveする時に構文エラーがないかチェックしてからsaveしてくれます。

ちなみにちなみに、一般ユーザの状態で直接 sudo vim /etc/sudoers とかして構文エラーがある状態でsaveしちゃうとそれ移行のsudoが一切できなくなるので察してください。 考えただけでも胸がドキドキしますね!

PHP 7.0.3 をインストールするためにconfigureオプションについて調べた

php

2016年2月4日に PHP 7.0.3 がリリースされましたね。

PHP: News Archive - 2016

よく訓練されたPHPerな僕は最新版をビルドしようと ./configure すると色々怒られた(多分7.0.2のビルドのときにもコケてたはずだけど気づかなかった)ので、改めて標準的な構成でPHPをビルドするためのオプションを調べたので備忘録代わりにメモっときます。

./configure \
--prefix=/usr/local/php7 \
--with-config-file-path=/usr/local/php7/etc \
--without-pear \
--enable-sockets \
--enable-zip \
--with-openssl \
--enable-cgi \
--enable-pdo \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--enable-embedded-mysqli \
--with-pdo-sqlite \
--with-readline \
--enable-mbstring \
--disable-debug \
--enable-fpm \
--enable-opcache

上でconfigureすれば、

  • pearは使わない

  • pdo(mysql)が使える

  • php-fpmが使える

  • opcacheが使える

  • 日本語が使える

  • インタラクティブシェルが使える (--with-readline をつけないと php -a ってやってもインタラクティブモードになってプログラムの実行に Ctrl + D のタイプが必要になる)

という感じです。

これは今日まで知らなかったのですが、PHPでプロセス管理したい!っていう特殊なニーズをお持ちの方向けに --enable-pcntl でフォーク出来るようになるっぽいです。

PHP: PCNTL - Manual

PHPでもforkがしたい! | ADN LAB's Blog

自分でビルドしたい人の参考になると嬉しいです。