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

gorogoroyasu

福岡の開発会社で働いている。

タブ区切りのファイルからPHP の配列を作り出すためにやったこと。

PHP

タブ区切りのファイルからPHP の配列を作り出すためにやったことを書いていきます。

やりたかったこと。

[
    ['hoge' => 'name1', 'fuga' => 'namae1'],
    ['hoge' => 'name2', 'fuga' => 'namae2'],
    ['hoge' => 'name3', 'fuga' => 'namae3'],
    ・
    ・
    ・
];

みたいな配列を作りたかった。

元データは、

hoge fuga
name1 namae1
name2 namae2
name3 namae3
name4 namae4
name5 namae5
name6 namae6

みたいなの(読み込むやつ.csv)。これがTSV になってた。

とりあえずググった。見つけたのはこれ。

qiita.com

なるほど。CSV ならうまいこと変換できるのか。

ということで、おもむろにatom を開き、 tab を全部 カンマに置換した。
これで、CSVの完成(たぶん)

書いたコードはこんだけ。

readCSV.php

<?php

$file = new SplFileObject('./読み込むやつ.csv');
$file->setFlags(SplFileObject::READ_CSV);
$array = [];
foreach ($file as $line) {
    $array[] = [
        "'hoge'" => "'".$line[0]."',",
        "'fuga'" => "'".$line[1]."',",
    ];
}
print_r($array);

そして、
php readCSV.php > text.txt

を実行。
できた配列の書き出しとか作るとめんどくさいからね!

そして、text.txt をエディタで開く。
ARRAY が含まれている行を全部削除
-> ([に全置換
-> )],に全置換

これで、全部配列に変換された。

一件落着。

全部変換してくれるプログラムが理想だけど、
別に何度も使うものじゃなかったら、これぐらい手動のオペレーションがあってもいいよね?

後日談

頑張ったのに、こんなのあった。 このスクリプト使えば、 TSV -> 配列の変換簡単じゃん!
tab をカンマに置き換える とかしなくてよかったじゃん!

qiita.com

とおもったけど、後の祭り。
ということで、皆さんご自由にお使いください(ほとんど丸コピだけど。。。)

なにはともあれ、出来る限り簡単にデキるようにつくったから、ダメージはほとんどない。
よかった。

空のフィールドに独自のバリデーションをかける方法

CakePHP3 CakePHP3

CakePHP3 を使っていて、少し特殊なバリデーションを書く機会に遭遇した。

例)

add.ctp

$this->Form->create($entity);
$this->Form->input('hoge');
$this->Form->input('fuga');
$this->Form->submit('submit');
$this->Form->end();

ExamplesController.php

public function add()
{
    $entity = $this->Examples->newEntity();
    if ($this->request->is('post') {
        $tmp = $this->Examples->patchEntity($entity, $this->request->data);
        if ($this->Examples->save($tmp) {
            // something
        }
        $this->set(compact('entity'));
    }
}

という状況で、

fuga に値が入っている場合は、hoge は何か入力されている必要がある。
hoge に値が入っていても、fugaに値が入っている必要はない。

という仕様を考える。

一番簡単なのは、

ExamplesTable.php

public function validationDefault(Validator $validator)
{
    $validator
    ->allowEmpty('hoge');
    $validator
    ->allowEmpty('fuga')
    ->add('fuga', 'custom', [
    'rule' => function ($value, $context) {
        if (!empty($context['data']['fuga'] && empty($context['data']['hoge']) {
            return false;
        }
        return true;
    },
    ['message' => 'fuga を入力する際は、hogeも入力して下さい']
    ]);
}

を使って書いていく方法だろう。

ただ、この方法には問題がある。
それは、
「fuga を入力する際は、hogeも入力して下さい」というメッセージが
fuga に対して出現することだ。

本当に指摘したいのは、"hoge" が空欄であることなのに。。。

そして、そのための方法として考えられるのが、

$entity->errors();

を利用してエラーをセットすること。

しかし、残念ながら、 ‘fuga'につけられたエラーを unset する方法を見つけることができなかった。

とうことで、あえなく断念。
たぶん何か方法があるので、ご存じの方は教えてください。

次に考えつく方法は、

public function validationDefault(Validator $validator)
{
    $validator
    ->add('hoge', 'custom', [
    'rule' => function ($value, $context) {
        if (!empty($context['data']['fuga'] && empty($context['data']['hoge']) {
            return false;
        }
        return true;
    },
    ['message' => 'fuga を入力する際は、hogeも入力して下さい']
    ]);

    $validator
    ->allowEmpty('fuga');
}

だ。
しかし、この方法はうまく機能しなかった。

$this->request->data['hoge']が空文字の場合、
Validation をすり抜けてしまうからだ。

ということで、最終的に見つけたのがこちら。

public function validationDefault(Validator $validator)
{
    $validator
    ->allowEmpty('hoge', function ($context) {
        $hoge = $context['data']['hoge'];
        $fuga = $context['data']['fuga'];
        if (!empty($fuga) && empty($hoge)) {
            return false;
        }

        return true;
    },
     ['fuga を入力する際は、hogeも入力して下さい'']
    );

    $validator
    ->allowEmpty('fuga');
}

という書き方だ。

https://api.cakephp.org/3.3/class-Cake.Validation.Validator.html#_allowEmpty
に書いてある。

この方法を使えば、上記の例の要な場合も簡単に対応できる!
いやー、便利ー!

CakePHP3 on Atom

Advent Calendar 2日目です。

本当は、"新卒がCakePHP3を半年ぐらい勉強した話 など" を書こうかと思っていましたが、
Atom の Advent Calendar も空いてたのでAtomCakePHP 開発する時にこうやってるよ的な記事が見当たらなかったので、
俺のAtom プラグイン達をそっと公開することにした。(公開してくださってる方々、本当に日々感謝しております。)
俺、実はこれ使ってるよ! 的なやつがあればぜひ教えてください!!!

言い訳

新卒未経験で入社したくせに
PHP書く人が誰も使っていたいエディタを使って開発しているはぐれもののブログです。
間違ってるところ、こうした方がいいよというところは、 優しく 教えてください!

開発環境

vagrant の var/www/html/hoge を、 mac の ~/sshfs/hoge にマウントしています。
wadap.hatenablog.com
sshfs の使い方は割愛させて頂きます。

俺のAtom プラグイン

  • atom-beautify
    atom-beautify
    php-cs-fixer を使ってコードを綺麗に成形してくれるやつ。
    動作は多少重いが、GitHub 上にあるコードが全部綺麗になってるから嬉しい!
    (あと、プロジェクトで git の pre-commit でphp-cs-fixer が強制的に動くからその対策も兼ねてる。)

  • cakephp3-snippets
    cakephp3-snippets
    CakePHP3 のコードをいい感じに手助けしてくれるツール。
    ただ、完全ではないので、github にプルリクを送りたい。
    いや、送る!
    もう一回、Advent Calendar かいてやる!!!

  • atom-autocomplete-php

  • autocomplete-php
    atom-autocomplete-php
    autocomplete-php
    PHP を補完してくれるやつ。
    よく分からず2つとも入れてる。
    競合していないか心配だが、今のところ問題なさそうなのでOK
    美味しいもの × 美味しいもの = 超美味しいもの
    という理論。

  • color-picker
    color-picker
    色馬鹿な人には必須!
    これを使えば、 #cacaca が灰色だってすぐ分かる(当たり前)

  • editorconfig
    editorconfig
    複数人で開発するなら必須だと思う!
    ちなみに使ってる.editorconfig ファイルはこんな感じ!

; This file is for unifying the coding style for different editors and IDEs.
; More information at http://editorconfig.org

root = true

[*]
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
char_set = utf-8  

[*.{html,css,js,ctp}]
indent_size = 2

[*.yml]
indent_style = space
indent_size = 2
/**
  * [hoge description]
  * @return [bool]
  */
public function hoge ()  
{
  return true;
}

みたいな、PHP doc を生成してくれるやつ!
使い方は非常に簡単!
public function hoge()の上の行で
/** って書いてエンター押すだけ!

  • file-icons
    file-icons
    なんとなく入れてる。

  • goto-definition
    goto-definition
    関数とかクラスとかの上にマウスをホバーさせると、PHP doc の内容を表示してくれる。
    また、カーソルを当てて Alt-Cmd-Return を押すと、
    宣言元に飛んでくれる。
    超便利!
    (Alt-Cmd-Returnは、この記事書いてて知った。書いてよかった!)

  • highlight-column
    highlight-column

縦線入れてくれるやつ。
HTML の対応とか見るのに便利!
あと、トイレとか行って戻ってきた時自分がどこにいるのか見失いにくい!

  • japanese-wrap
    japanese-wrap
    これは一番はじめに入れたプラグインの一つ。最古参。
    ないと日本語書くのが辛いらしい。

  • todo-show
    todo-show
    TODO とか FIXME とか NOTE とかをハイライトしてくれるやつ。

  • minimap
    minimap

自分がどこにいるのかがひと目で分かるminimapを表示してくれるプラグイン
でかいファイルになると、自分がどこにいるか分からず絶望的な気持ちになる。

と、こんな感じです。

逆に、入れてる人が多いようだけど入れていないのは、

  • emmet
    emmet
    入れたら、めちゃくちゃキーバインドが衝突したので外した。
    Ctrl+F とか Ctrl+B とかが使えなくなるのは致命的。

  • cakephp-snippets
    cakephp-snippets
    あまり補完してくれなかったから使うのをやめた。
    わがまま。

と、こんな感じです。

ついでなので、よく使うショートカットも書いておきます。

  • Ctrl + P, Ctrl + N, Ctrl + F , Ctrl + B
    前後左右のコマンド。
    これがないと死ぬ。

  • Ctrl + A , Ctrl + K, Ctrl + E
    行頭に戻る
    行末へ行く
    カーソルより後ろを削除 (切り取り)
    特に Ctrl + A は、スペースやタブを無視して行頭へ行ってくれるのがありがたい!

  • Cmd + D
    同じ変数を選択してくれるやつ。
    変数名を帰る時に便利!

  • Cmd + Alt + Return
    上述の、関数やクラスの宣言元を探してくれるやつ!
    今日から一軍の仲間入り!

  • Cmd + Shift + F
    プロジェクト全体検索 わりと時間かかるし、mac が 「ういーーーん」って言い出すけどよく使う。

  • Ctrl + Shift + ]
    どなたかのブログを拝見して、このキーにオートインデントを割り当てた。
    超便利!!!

  • Ctrl + Shift + M
    マークダウンのプレビュー 地味に便利!

  • Cmd + Shift + P
    プラグイン入れよう! と思ったらここ!

  • Cmd + L
    一度押すと、一行選択してくれる。
    二回以上押すと、順次下の行を選択していく

  • Cmd + T
    大事なの忘れてた!
    プロジェクト内のファイルを探すやつ!
    途中文字を抜かしてもいい感じに探してきてくれて便利!

すごくよくまとまっていて、よく参考にさせていただいてます!
http://qiita.com/YusukeHosonuma/items/0f687b16f0d5eeb0c18f

という感じです。
今後、変わっていくかもしれないけど、現時点では! という感じで書きました!
逆に CakePHP 書いてる人で、いいプラグイン知ってるよ?とか、こんなの作ったよ? って言う方がいらっしゃいましたら、
コメントなりなんなりでお知らせ下さい!
喜びます!

一言

頑張ってプルリク送ります!
あと、この記事が、Atom 使おうかな? とか、使ってる とかいう CakePHP3 ユーザーの目に止まり、お役に立てるとうれしいです!!!

twitter => @gorogoroyasu
フォローとかしてもいいんですよ!!!

[補足] これ、CakePHP3 関係なくね? というご指摘をいただきました。
もしかしたらCakePHP3 は、書き直すかも。。。

Maximum function nesting level of '256' reached, aborting!

PHP PHP

タイトルのエラーが発生したので原因を調べた。

何を言ってるかよくわからなかったので、ググった。

参考サイト1
参考サイト2

発生状況とかを書いておこうと思う。

CakePHP3 を使用 HogeBehavior.php を 読み込んだ。

UsersTable.php

public function initialize ()
{
    parent::initialize();
    $this->addBehavior('Hoge');
}
// 続きのコード

そして、 HogeBehavior.php の中に問題があった。

use Cake\ORM\TableRegistry;

public initialize ()
{
    parent::initialize();
    $this->Users = TableRegistry::get('Users');
}

Users から読み出す HogeBehavior.php の中で
TableRegistry::get('User') をしていたのだ。

原因がわかったので一件落着。

結論

UserTable から読み込む Behavior の中で TableRegistry::get('User'); をしてはいけない。

原因調査 だが、せっかくなので事故原因を調査してみた。
vendor の中を読む。

まず、use \Cake\ORM\TableRegistryとあるので、 TableRegistry の中を読みに行った。

すると、public static function get($alias, array $options = [])という メソッドが見つかった。

このメソッドは、static::locator()->get($alias, $options) をreturn している。
そして、この return の前で error が出ているらしかったので、更に深く潜った。

ところで、

return static::locator()->get($alias, $options);

という書き方は、遅延静的束縛というらしい。 このクラスを継承しているクラスのオブジェクトからこのメソッドが呼ばれた場合、 継承先のlocator()を読み込むという書き方らしい。(説明が難しいし微妙に違いそう。)

しかし、今回は直接このクラスを呼んでいるので、

return self::locator()->get($alias, $options);

と等価だ。(と思う)

ということで、 \Cake\ORM\TableRegistry クラスの中の

public static function locator(LocatorInterface $locator = null)

を呼んでいる。

このクラスの返り値は

static::$_locator;  

であり、ありがたいことにコメントで

* @var \Cake\ORM\Locator\LocatorInterface  

とある。

つまり、

Cake\ORM\Locator\TableLocator

が返ってくる。
すなわち、

return static::locator()->get($alias, $options);

の中の

static::locator() = Cake\ORM\Locator\TableLocator

となる。

そこで、Cake\ORM\Locator\TableLocatorクラスのget()メソッドを探しに行った。

この、179行目、

$this->_instances[$alias] = $this->_create($options);

で呼んでいる、

protected function _create(array $options)

が今回のエラーの原因だった。

このメソッドの中で

return new $options['className']($options);

という風に
$options['className']($options) を繰り返し new して返している。
ここがポイントだった。

つまり、

TableRegistry::get('User');

により、UsersTable クラスのオブジェクトが生成される。 そして、UsersTable クラスの

public function initialize() 

が動き、もう一度

$this->addBehavior('Hoge');

が呼ばれる。 そして、TableRegistry が動きまたUsersTable クラスが new される。

この繰り返しが256回おこり、 参考サイト1 に書いてあるエラーが起こったのだった。

これが事故原因。

解決方法は、

Cake\ORM\TableRegistry

の使い方に気をつける。

という話でした。

vendor の中見るのたのしー!

感想

なんか、全体的に感想文みたいになってしまったが、
vendor の中を見るのがこんなに楽しいとは思わなかった。
これからも継続して読んでみようと思う。

今時の若いもんは、Windows10をクリーンインストールしてCentOS5.5をインストールすることもできんのか。

今時の若いもんは。。。

今時の若いもんは、vagrant とか docker とか使って楽ばっかりしよってから。 なっとらんばい。

ということで、福岡県で働いています。 今日も福岡は平和です。

さて、表題のとおりですが、色々あってWindows10 がプリインストールされたマシンをクリーンインストールして、CentOS5.5 を入れようという話になりました。 で、弊社の新人が担当することになりました。

しかしこの世代、ゆとりゆとりと言われていますが、まさかここまでひどいとはね。 まさかCentOS入れるのに5時間もかかるとはね。 がっかりですよ。今時の若いもんは。。

という声が聞こえて来そうな大失態を犯した新卒が僕です。 いやー。辛かった。

ということで、表題どおりですが、今日業務でWindows10がプリインストールされたマシンにCentOS5.5を入れました。

僕は、大学時代ゲームをやってたので、SSD 買ってきてWindows インストールとか時々やってました。 だから、余裕だと思っていました。

え? Windows10 って、Daemon Tool 使わなくていいんでしょ?楽勝じゃないすか?www ぐらいののりでした。

仕事をなめてます。はい。少なくとも今日に関しては。。。

ということで、ハマった話です。

CentOS5.5 ってどっから入手できるんだっけ?

最初のハマリポイントは、OSの入手方法です。 実は、以前 http://blog.fusic.co.jp/archives/3796/ を参考に、CentOS6.6 を使ってvagrant box を作ったことがありました。 だから、isoとかいうファイルをネットからダウンロードしてくればいいんでしょ?楽勝ですね! って言う感じでした。

ところが、

という感じで、どこにも置いてないんですね。 どこも、Readme だけのもぬけの殻。

http://qiita.com/timothy_o/items/d7d7b8de23b426eddf2f をみつけて探してみても、 http://archive.kernel.org/centos-vault/5.5/isos/x86_64/ liveDVD.iso がない。

詰みです。

先輩に泣きつきました。

すると、 倉庫から、秘伝の"CentOS5.5が入ったDVD"が出てきたのです。 驚きました。喜びました。 道端で1万円もらった気分でした。 もらったことないけど。

ということで、無事、インストールディスクも見つかりました。 さて、仕事開始です!

人生はそんなに甘くない。

DVD も手に入れたし、あとはBios を立ち上げてドライブ起動順を切り替えれば終わり♪ と、意気揚々とスキップしながら倉庫から出てきました。

BIOS の設定で、SafeMode なるものがあったので、一応disable にし、 UEFI モード とかいう設定をオフにしました。 そして、起動順を切り替えました。

そのまま、設定を保存すると、画面には、 Welcome To CentOS と書いてあるではないですか! 僕の喜びは絶頂です。 仕事ってこんなに楽で良かったんだっけ? って思いながらほいほい次へ進みました。

しかし、そのときはやってきました。

全てのパーティションを削除して上書きする(英語は忘れた)的なやつに "はい" と押す。 その後、 "ほんと?" と聞かれたので、"はい"を押しました。 すると、 設定とかいじる? と聞かれたので、 "はい" を押しました。

そして、なんかでかい画面が出てきました。

エラー!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! f:id:adiboy:20160930230108j:plain

だとさ。 解決方法はqiitaにあげてます。

http://qiita.com/gorogoroyasu/items/117d85938a60cdb269de

疲れたのでこの辺で。

何が言いたいの?

もっとサーバーに詳しくならなくてはならないなと反省しました。 LPIC の本買ったんで、読みます。 しかし、CentOS5系とか、これから先触ることがあるのだろうか。。。

CakePHP3のガラケー対応プラグイン作った!その名も Garak!

僕のスマホ遍歴

突然だが、僕のスマホ遍歴の話をしようと思う。
僕は、2011年までガラケーを使っていた。
最初のスマホは、 iPhone4Sだった。
それからかれこれ5年間。
ずっとスマホを使い続けている。
僕のスマホ遍歴はこんな感じ。

iPhone 4S  
iPhone 4 (4Sがアスファルトに直撃して画面が全壊したのでヤフオクで購入。この子は最終的に裏面が全壊)  
iPhone 5S  
arrows M02 (あまりに動作が遅く、親に譲った。使用期間半年。)
iPhone SE (←今)

ずっとiPhone を使っていたからAndroid を偵察してみよう! と思って買った arrows M02 が想像以上の遅さで、
これまで以上にiPhone が好きになった。

ちなみに、最後に使ってたガラケーのことはさっぱり覚えてない。

ガラケー対応プラグインの必要性

そんな僕が、ガラケー対応のプラグインを作成した。
理由は、スマホのシェアがそこまで高くないから。
ここにシェアがまとめてある。
www.nikkei.com

その中から抜粋すると、
スマホの普及率 : 67.4%(前年度比6.8ポイント増)
スマホ以外の普及率 : 64.3%(前年度比5.5ポイント減)
という感じ。
(なぜか合計が100% ではないのはご愛嬌)

依然としてガラケーユーザーもいる模様。
(ガラケーでWeb サイトを閲覧する人がどれだけいるのかは別の話。通話はガラケーとかいうめんどくさい選択をしている人もいるし。。。)

しかし、なぜガラケー用のプラグインなるものが必要になるのか?
それは、、、

PC、スマホガラケーでは、色々な違いがあるから。

たくさん違いがあるが、個人的に重要だと思う違いは、
1) 文字コード
2) クッキー使用の可否
3) 外部CSS の読み込み
4) JavaScript 使用の可否
の4つ。
それぞれ簡単に説明していく。

1) 文字コード
最近のPC,スマホサイトには、文字コードは"UTF-8" が採用される。
しかし、ガラケー文字コードは"Shift-JIS" である可能性が高い。
可能性が高いと言っているのは、
携帯キャリア、製造年月によってはUTF-8 が使用できることがあるからだ。
しかし、大事なのは、文字コードは "Shift-JIS" を使った方が安全だということだ。
ということで、全ての文字は、 UTF-8 から Shift-JIS に変換されなくてはならない。
めんどくさい。

2) クッキー使用の可否
基本的に、ガラケーではクッキーを使うことができない。
では、どうやってログイン情報等を管理するか?
URL の末尾にセッションID をつける。
それにより、ログイン情報等を管理する。
実に原始的。めんどくさい。

3) 外部CSS の読み込み ガラケーでは外部CSS が使用できない(ことが多い)。
そのため、CSS を直書きする必要がある。

<div class="hoge" style="color: green;">hoge</div>   

みたいな感じ。
めんどくさい。

4) JavaScript 使用の可否
基本的にガラケーではJS を使うことができない。
悲しい。

と、ざっくり上げただけでも4つの違いがある。
特に面倒くさいのは1) と 2) 。
ここらへん、なんとかしたい!!

作ったプラグイン

ということで、 上記 1) と 2) をいい感じで解決するプラグインを作った。
本当は 3) もなかなかめんどくさいんだけど、
いい感じにテンプレートとか拾ってきて対応して下さいー。

プラグインはcomposer を使って ここ からインストールできます。
名前は、 "Garak" !

ぜひ使ってみて下さい。

と、言いたいけど、
このプラグインが不要になる日を楽しみにしています。