Twigでforeachする

for inでforeachができる

<ul id="users">
{% for user in users %}
<li><a href="/user/{{ user.name | url_encode }}">{{ user.nickname }}</a></li>
{% endfor %}
</ul>

構文的にはJavaScriptみたくkeyが渡ってきそうなんだがな

PHPでnullとか文字列をarrayでキャストしてみたらこうなった

返ってくる値が定まっている方が便利なんだけどそうなっていないことが多い。こんな時は(array)でキャストするとがっちり配列のつもりで扱えるんだけど、心配なので調べてみる

<?php
var_dump((array) null);
var_dump((array) 1);
var_dump((array) 'text');
var_dump((array) true);
var_dump((array) false);

基本配列じゃなかったら配列にして先頭に突っ込んでくる感じかね。nullは空配列ってのも気持ちがいい

$ php test.php
array(0) {
}
array(0) {
}
array(1) {
[0]=>
int(1)
}
array(1) {
[0]=>
string(4) "text"
}
array(1) {
[0]=>
bool(true)
}
array(1) {
[0]=>
bool(false)
}

こうなってほしいって結果にだったな

PHPの連想配列の先頭と末尾のキーを取る

連想配列のいろんなキー取得してみる

<?php
$list = [
'test1' => 'jpge',
'test2' => 'jpge2',
'test3' => 'jpge3'
];
// デフォは最初なんで最初のキー
echo key($list) . "\n";
// こうすれば末尾のキー
end($list);
echo key($list) . "\n";
// こうすれば先頭のキー
reset($list);
echo key($list) . "\n";

結果はこうだった

$ php test.php
test1
test3
test1

PHPでメールアドレスやURLをfilter_var()で判定

filter_var()は検証フィルタを利用して与えた変数を検証してくれる。テストコードを書きまくるが、検証したい値が多いのでまとめて実行したいんだが、var_dump()をそのまま出力すると見辛いのでこんな関数を用意していくのでブラックジャックによろしく

<?php
function get_var_dump($value) {
ob_start();
var_dump($value);
return ob_get_clean();
}

メールアドレスかを判定する

<?php
$list = [
'info@hatena.ne.jp',
'@hatena.ne.jp',
'hoge'
];
array_map(function($value) {
echo trim(get_var_dump($value));
echo ' => ';
echo trim(get_var_dump(filter_var($value, FILTER_VALIDATE_EMAIL)));
echo "\n";
}, $list);
$ php test.php
string(17) "info@hatena.ne.jp" => string(17) "info@hatena.ne.jp"
string(13) "@hatena.ne.jp" => bool(false)
string(4) "hoge" => bool(false)

trueっぽい奴にtrueを返す

<?php
$list = [true, false, 'on', 'true', 'yes', '1', 1, 0, null, 'null', 'ok'];
array_map(function($value) {
echo trim(get_var_dump($value));
echo ' => ';
echo trim(get_var_dump(filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)));
echo "\n";
}, $list);

falseっぽいやつにfalse返してるけど、よくわからなくなるとnullを返してるんかね

$ php test.php
bool(true) => bool(true)
bool(false) => bool(false)
string(2) "on" => bool(true)
string(4) "true" => bool(true)
string(3) "yes" => bool(true)
string(1) "1" => bool(true)
int(1) => bool(true)
int(0) => bool(false)
NULL => bool(false)
string(4) "null" => NULL
string(2) "ok" => NULL

整数化どうか

こっからはフィルターって感じの動きになるみたいよ

<?php
$list = [
10.5,
20,
true,
'a'
];
array_map(function($value) {
echo trim(get_var_dump($value));
echo ' => ';
echo trim(get_var_dump(filter_var($value, FILTER_VALIDATE_INT)));
echo "\n";
}, $list);

多分思想的にはifとかにそのまま突っ込んで動くからそのまま値返してるんじゃないかと思う。あと名称通り正常ならフィルターしてそのまま返すってことになるしな。

$ php test.php
float(10.5) => bool(false)
int(20) => int(20)
bool(true) => int(1)
string(1) "a" => bool(false)

floatかどうか

<?php
$list = [
10.5,
20,
true,
'a'
];
array_map(function($value) {
echo trim(get_var_dump($value));
echo ' => ';
echo trim(get_var_dump(filter_var($value, FILTER_VALIDATE_FLOAT)));
echo "\n";
}, $list);

floatだったらそのまま返して違えばfalseらしい

$ php test.php
float(10.5) => float(10.5)
int(20) => float(20)
bool(true) => float(1)
string(1) "a" => bool(false)

IPアドレスかどうか判定

<?php
$list = [
'127.0.0.1',
true,
'a'
];
array_map(function($value) {
echo trim(get_var_dump($value));
echo ' => ';
echo trim(get_var_dump(filter_var($value, FILTER_VALIDATE_IP)));
echo "\n";
}, $list);

IPアドレスなら文字列でそれを返す

$ php test.php
string(9) "127.0.0.1" => string(9) "127.0.0.1"
bool(true) => bool(false)
string(1) "a" => bool(false)

URLか判定する

<?php
$list = [
'http://example.com',
'example.com'
];
array_map(function($value) {
echo trim(get_var_dump($value));
echo ' => ';
echo trim(get_var_dump(filter_var($value, FILTER_VALIDATE_URL)));
echo "\n";
}, $list);

URLなら文字列で違うならfalse

$ php test.php
string(18) "http://example.com" => string(18) "http://example.com"
string(11) "example.com" => bool(false)

PHPのob_start()でvar_dump()の出力結果を文字列で受け取れる

ob_start()は出力のバッファリングができるようになるらしい。これを実行して何らかの停止的なものを動かすまで出力は行われずにバッファに溜まっていくとか何とか。

<?php
ob_start(function($buffer) {
return (preg_replace('/福士蒼汰/', 'hoge', $buffer));
});
echo 'I love 福士蒼汰';
ob_end_flush();

私のこと好きなの?

$ php ob_start.php
I love hoge

ob_start()はコールバックで溜め込んだバッファを受け取れるので、バッファの内容を書き換えたりいいことできるってわけだな。

最後にob_end_flush()ってのを書いているけど、これを書くことで溜め込んだバフッファを吐き出してバッファを終了するってわけなんだが、ob_get_clean()を使えばバッファを終了しつつバッファの内容を文字列で取得することができる。ob_get_crean()は内部的にはob_get_contents()ob_end_crean()を実行している。

ob_end_clean()ってのはバッファを出力せずに終了したりできる。バッファの内容をob_get_contents()で文字列として受け取ることができるんだが、受け取るだけで出力はしたくないって時はob_end_crean()を使えばいいってしろものだったんだが、ob_get_crean()があるからこの2つが目的なら使わなくていい。まあここはそういう感じで動かすこともできるんだなってわかってばおっけい!

さっそく実践編

3行で行ける

<?php
ob_start();
var_dump(true);
$result = ob_get_clean();
echo '=> ';
echo $result;

出力結果はこう

$ php var_dump.php
=> bool(true)

関数化してもイケる

与えた変数のvar_dump()の結果を文字列で返す

<?php
function get_var_dump($value) {
ob_start();
var_dump($value);
return ob_get_clean();
}

こうやって使う

echo get_var_dump('変数とか渡すだけ');

print_r()が文字列で結果を返してくれるんだからvar_dump()が文字列で受け取れるようになっても別にいいと思うんだがな

Thanks

stackoverflow.com

Twigでescapeさせない

Twigはデフォルトでhtmlspecialchars()的なescapeが動くんだがコード貼り付けたりする時にescapeしたくないなあって時はこれでそのまま出力できる

{{html|raw}}

PHPの &amp;quot;It is not safe to rely on the system&amp;#39;s timezone settings&amp;quot; エラーを解決する

ちっ!腐ってやがる!

Warning: date(): It is not safe to rely on the system's timezone settings. You are required to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /Users/hoge/test.php on line 4

これで定義するのがとりあえず早い

date_default_timezone_set('Asia/Tokyo');

ほらね、怖くない。ね?怯えていただけなんだよね。