5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PHPで湯婆婆を短く書く

Posted at

#はじめに
この投稿は @Nemesis さんの Javaで湯婆婆を実装してみる をはじめとした湯婆婆ムーヴに乗っかったものです。
@TD12734 さんの HTMLで最も短い湯婆婆(記事内で試せます) に触発されPHPでも短く書けないか試してみました。

#とりあえず普通に書く

<?php
$realName = "安達桜";
$splittedRealname = mb_str_split($realName);
$newName = $splittedRealname[array_rand($splittedRealname)];

echo 'フン。' . $realName . 'というのかい。贅沢な名だねぇ。今からお前の名前は' . $newName . 'だ。いいかい、' . $newName . 'だよ。分かったら返事をするんだ、' . $newName . '!!';
// 実行結果
// フン。安達桜というのかい。贅沢な名だねぇ。今からお前の名前は桜だ。いいかい、桜だよ。分かったら返事をするんだ、桜!!

マルチバイトの扱いの関係で多少冗長になってしまいましたが、文字列を mb_str_split()することで配列化することができます。
その配列の中からランダムに1つを取り出すことで新しい名前が無事決まりました。

#名前を外部から与えられるようにする

yubaba.php
<?php
$splittedRealname = mb_str_split($_GET['realname']);
$newName = $splittedRealname[array_rand($splittedRealname)];

echo 'フン。' . $_GET['realname']. 'というのかい。贅沢な名だねぇ。今からお前の名前は' . $newName . 'だ。いいかい、' . $newName . 'だよ。分かったら返事をするんだ、' . $newName . '!!';

幸いにしてPHPではURLにクエリを付与することにより外部から入力を与えることができます。
この例でしたらブラウザからアクセスする際に yubaba.php?realname=安達桜 とすることで最初に書いたプログラムと同等になるはずです。多分。

#コードを短くしていく

yubaba.php
<?="フン。".($r=$_GET['r'])."というのかい。贅沢な名だねぇ。今からお前の名前は".($n=mb_str_split($r)[rand(0,mb_strlen($r)-1)])."だ。いいかい、{$n}だよ。分かったら返事をするんだ、{$n}!!";

($r=$_GET['r'])($n=mb_str_split($r)[rand(0, mb_strlen($r)-1)])の部分は変数への代入と表示を一括して行っています。
さらにPHPでは文字列をダブルクォートで括ることで、その文字列中の{}内は変数展開が行われるため文字数省略には有用なテクニックです。

#PHPのバージョンを5.3まで下げる

yubaba.php
<?="フン。{$r}というのかい。贅沢な名だねぇ。今からお前の名前は".($n=preg_split('//u',$r)[rand(1,mb_strlen($r)-1)])."だ。いいかい、{$n}だよ。分かったら返事をするんだ、{$n}!!";

PHP5.3では悪名高いregister_globalsが使用可能です。(register_globalsについては下記の記事をご参照ください)
PHP 5.4 以上でも register_globals を再現するライブラリ MercifulPolluter

こちらを有効にすることで$_GET['r']をわざわざ書かなくて済むようになります。なんて便利なんだ。
その代わりPHP7で追加されたmb_str_splitが使用できなくなってしまいますので、代わりにpreg_split('//u',$r)を使用しました。
ただし、このままだと分割した配列の最初と最後が空文字になってしまうため、randの範囲を調整することで空文字部分を選ばないようにしています。

#名前をシングルバイト文字前提とする

yubaba.php
<?="フン。{$r}というのかい。贅沢な名だねぇ。今からお前の名前は".($n=str_shuffle($r)[0])."だ。いいかい、{$n}だよ。分かったら返事をするんだ、{$n}!!";

マルチバイトで扱おうとするからコードが冗長になるのです。
シングルバイトを前提にすれば1文字抜き取る部分はstr_shuffle($r)[0]だけでよくなります。

ちなみにこちらで無理やりマルチバイトの名前を通すと文字化けします。

yubaba.php
<?php
$_GET['r']="安達桜";
?>

<?="フン。".($r=$_GET['r'])."というのかい。贅沢な名だねぇ。今からお前の名前は".($n=str_shuffle($r)[0])."だ。いいかい、{$n}だよ。分かったら返事をするんだ、{$n}!!";

//実行結果
//フン。安達桜というのかい。贅沢な名だねぇ。今からお前の名前は�だ。いいかい、�だよ。分かったら返事をするんだ、�!!

#ファイル名を変える
仕上げにファイル名を湯婆婆のセリフとして問いかけも実装すれば完成です。
アクセスする際のURIは契約書だよ。そこに名前を書きな。.php?r=adachisakuraのようになります。

契約書だよ。そこに名前を書きな。.php
<?="フン。{$r}というのかい。贅沢な名だねぇ。今からお前の名前は".($n=str_shuffle($r)[0])."だ。いいかい、{$n}だよ。分かったら返事をするんだ、{$n}!!";

#終わりに
出かけるつもりが1時間も記事作成に費やしてしまった…

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?