Pages

ラベル PHP の投稿を表示しています。 すべての投稿を表示
ラベル PHP の投稿を表示しています。 すべての投稿を表示

2023年7月11日火曜日

PHP5.3 環境でcomposer self-update して動かなくなった時

RHEL6 ELS の環境で composer self-update をしてしまったようで、アップデートされたけど同時に comopser が壊れてしまった。。
$data が何やら invalid foreach だの。。

前にもあったが composer は環境の phpのバージョンを見てアップデートした良いかを判別しておらず、動かなくても更新しちゃうクールなやつ♪

って事で

$ composer self-update 1.7.2

を行うが 

[ErrorException]
Invalid argument supplied for foreach() 

チーン。。

って事で削除してインストールしなおす。

$ cd ~/
$ rm ./bin/comopser
$ cd ./bin
$ curl -sS https://getcomposer.org/installer | php -- --version=1.7.2
$ mv ./composer.phar composer

composer とは

Composerは、PHPプログラミング言語向けの依存関係管理ツールです。PHPのパッケージやライブラリのインストール、更新、バージョンの管理を容易に行うことができます。

Composerは、PHPアプリケーションの開発において、外部のライブラリやパッケージを利用する場合に特に便利です。通常、PHPのプロジェクトでは、複数のライブラリやパッケージが必要となることがあります。それらのライブラリやパッケージの依存関係を手動で管理するのは困難で時間がかかるため、Composerを使用することで効率的に管理することができます。

Composerは、プロジェクトのルートディレクトリに配置される`composer.json`と呼ばれる設定ファイルを使用して、必要なパッケージやライブラリを指定します。Composerは、指定された依存関係を解決し、自動的に必要なパッケージをダウンロードしてインストールします。

Composerは、PHPコミュニティで広く使用されており、多くのPHPフレームワークやプロジェクトで標準的な依存関係管理ツールとして採用されています。

composer をアップグレードする方法

Composer自体のアップデートは、コマンドラインで簡単に行うことができます。以下の手順に従って、Composerを最新バージョンにアップデートする方法を説明します。

1. ターミナルまたはコマンドプロンプトを開きます。
2. Composerがグローバルにインストールされている場合は、以下のコマンドを実行します:

 $ composer self-update

   Composerがローカルにプロジェクトごとにインストールされている場合は、プロジェクトのルートディレクトリで上記のコマンドを実行します。
   
   Composerがアップデートされ、最新バージョンに更新されます。

3. コマンドが正常に実行された場合、Composerは自動的に最新バージョンに更新されます。

なお、Composerをアップデートするにはインターネット接続が必要です。アップデート後は、最新の機能や修正が適用されたComposerを使用することができます。

comopser をダウングレードする方法

Composerを特定のバージョンにダウングレードするには、次の手順に従ってください。

1. ターミナルまたはコマンドプロンプトを開きます。

2. Composerの現在のバージョンを確認します。以下のコマンドを実行します:

$ composer --version

   現在のバージョンが表示されます。

3. ダウングレードしたいバージョンを指定してComposerをインストールします。以下のコマンドを実行します:

$ composer self-update <version>

   `<version>`の部分に、ダウングレードしたいバージョン番号を指定します。例えば、Composerを1.10.10にダウングレードする場合は次のようにします:

$ composer self-update 1.10.10

4. コマンドが正常に実行された場合、指定したバージョンのComposerがインストールされます。

ダウングレード後は、指定したバージョンのComposerを使用することができます。ただし、Composerをダウングレードする場合、そのバージョンに関連する制約や制限があるかもしれないことに注意してください。最新バージョンを使用することが推奨される場合もあります。

2023年4月27日木曜日

[CakePHP4] Controller から コマンドを実行する方法

$commandRunner = new CommandRunner(new Application(ROOT . DS . 'config'), 'cake');
$commandRunner->run([
    'bin' . DS . 'cake',
    'command_name',
    'param1',
    'param2,
]);

上記は

$ bin/cake command_name param1 param2

と同等。

2022年3月15日火曜日

[Laravel] Windowsにはcronが無いので、タスク スケジューラにscheduleを設定する

Windowsにはcronが無いので、タスク スケジューラに設定するんですが、単純に設定するとコマンドプロンプトのウィンドウが一分毎に立ち上がって文字入力の邪魔をする。。

なので、もうVBSファイルからコマンドプロンプトを実行するようにしてこれを回避。

ついでにPHPのバージョン変更もするように。


手順

  1. VBSファイルを作成
  2. タスク スケジューラに設定

VBSファイルを作成

VPSファイルはどこに置いても大丈夫です。
ただのテキストファイルなのでメモ帳で作成可能です。
拡張子は .vbs

記載内容はこちら

Set ws = CreateObject("Wscript.Shell") 
ws.run "cmd /k set PATH=D:\app\php-8.0.14-nts-Win32-vs16-x64;%PATH% & cd D:\prjects\sample & php artisan schedule:run", 0, false

記載内容の説明
ws.run で 3つのパラメータを指定しています。

1つ目 実行するコマンド
2つ目 ウィンドウオプション 0=表示しない
3つ目 同期指定 false=非同期

つまり 1つ目のコマンドは非表示で勝手に実行しといてくださいって感じです。

run メソッドについて詳しくはこちら

コマンドは & 区切りで複数実行できますので、今回は
  1. PATH の更新
  2. ディレクトリの移動
  3. scheduleの実行
をやっています。


2021年5月18日火曜日

[CakePHP4] bake template で index,view,add,edit 以外を追加

自分は
  • add.php
  • edit.php
  • index.php
  • view.php
以外にも form.php を作成していて、 add.php, edit.php からそれを呼び出して共通かしています。
なので、bakeコマンドで form.php も作ってほしい。

あと基本的には Bootstrap を利用しているので、テーマを自作してと。。
  • plugins/BootstrapTheme/templates/bake/Template/add.twig
  • plugins/BootstrapTheme/templates/bake/Template/edit.twig
  • plugins/BootstrapTheme/templates/bake/Template/index.twig
  • plugins/BootstrapTheme/templates/bake/Template/view.twig
  • plugins/BootstrapTheme/templates/bake/Template/form.twig
こんな感じ。

作成して 

$ ./bin/cake bake template

とするけど。。

いつも通り
  • add.php
  • edit.php
  • index.php
  • view.php
ができるだけ。。

form.php だけを追加するのは以下のようなコマンドでできるので、自分のそれで追加しています。。

$ ./bin/cake bake template samples form


2019年12月26日木曜日

[PHP] Amazon MWS API Feed のXMLをXSDファイルを利用してバリデート(検証)する

gontoraさんによる写真ACからの写真

Amazon MWS API を利用して出品する際にXMLで一覧を生成するのだが、その生成したXMLが正しいかを判別するために Amazon MWS API のドキュメントサイトで配布されている XSD を利用した。

http://docs.developer.amazonservices.com/ja_JP/feeds/Feeds_FeedType.html

注: XMLフィードの作成方法によっては、商品情報フィードではなく、アイテムフィードスキーマを使用するよう、出品者に求められます。

ほんまAmazon紛らわしいな。。
こんな紛らわしいのに開発環境提供してくれないし。。。

Item フィード
https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_1_9/Item.xsd

Product フィード
https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_1_9/Product.xsd

XSDを利用してのXML検証方法


$xml = new DOMDocument(); 
libxml_use_internal_errors(true);

$xml->load('./sample.xml');
 
if ($xml->schemaValidate('./validate.xsd')) { 
   echo "Success \n";
} 
else { 
    echo "Error \n"; 
    $errors = libxml_get_errors();
    foreach ($errors as $error) {
        echo display_xml_error($error, $xml);
    }
    libxml_clear_errors();
} 

function display_xml_error($error, $xml)
{
    $return  = $xml[$error->line - 1] . "\n";

    switch ($error->level) {
        case LIBXML_ERR_WARNING:
            $return .= "Warning $error->code: ";
            break;
         case LIBXML_ERR_ERROR:
            $return .= "Error $error->code: ";
            break;
        case LIBXML_ERR_FATAL:
            $return .= "Fatal Error $error->code: ";
            break;
    }

    $return .= trim($error->message) .
               "\n  Line: $error->line" .
               "\n  Column: $error->column";

    if ($error->file) {
        $return .= "\n  File: $error->file";
    }
}

2019年7月11日木曜日

[PhpStorm] 2019にバージョンアップしたらフォントが小さくて見にくくなった。。特にドットが酷い。。

自分はできるだけツールはデフォルトの設定で使うようにしている。

理由は環境の構築の時に設定が大変だから。。
頑張って設定してもバージョンアップしたらその設定ができるとは限らないから。。
作者がこのツールではこの設定が良いと思っているものがデフォルトだろうから。。

と、まー理由はどうでもいいけどライセンス更新と合わせて phpstorm 2019にアップデート。

2018の時は特にカラースキーマの変更だけで使えたんだけど、phpstorm 2019 にアップデートして明らかにフォント小さくなった。。

.(ドット) と [半角スペース] の区別ができない。。

それでも我慢した。。
もう無理。。。

って事で数ヶ月頑張ったけどやっぱり変更します。。

カラースキーマ: Monokai



フォント: Source Code Pro



あ~ スッキリ♪

2019年5月8日水曜日

PhpStorm 割引販売のご紹介


https://secure.samuraism.com/referral/8BAEF98D2EE87690D23BB03ED3A7F393

PhpStorm は300円しか割引ありませんが、無いよりは良いですしね。
サムライズムって会社は2018年8月くらい(?)からの日本正規代理店みたいです。

2019年3月26日火曜日

PHPソースからフロー図の自動作成 Visustin以外で

以前 Visustin というツールを利用してPHPのソースからフロー図を作成しようとしただけど、何かしっくり来ない。。

そして別のツールが無いかなと探していたらこんなブラウザアプリを発見した。

code2flow
https://code2flow.com/


無料プランもあるみたい。

早速トップページ画面右上の GET STARTED から試してみた。



自分は今、メインで CakePHP3 を利用しているので、サンプルソースに ブックマークチュートリアル を利用した。

ブックマークチュートリアル
https://book.cakephp.org/3.0/ja/tutorials-and-examples/bookmarks/intro.html

Gut Hub
https://github.com/cakephp/bookmarker-tutorial



早速ソースをコピペしてみるとこんな感じに。
ん~ さすがに見やすい! とはならないけど、コメントもオレンジで表示されてて便利だ。
ソースやフロー図のところをマウスオーバーすると対となる箇所にガイドが付いて解りやすい。

ソースレビューなどを行う時にこれは便利な気がする。

なかなかこまめに使う場面が自分には無いけども、良いものを見つけたかな。

2018年11月21日水曜日

[CakePHP3] 管理画面とそれ意外でCSRF用のCookieName(クッキー名)を変更したい

/src/Application.php のデフォルト指定をまず削除。
本当は設定を更新したかったが、方法が見つからず。。

$middlewareQueue->get(3) からできるかなと思ったけど無理だよね。。
てか名前も指定できるようになってたらいいのに。。
->add した瞬間にこれ実行してるのかな。。

まーとりあえず以下の方法で対応しました。

public function middleware($middlewareQueue)
{
    $middlewareQueue
        // Catch any exceptions in the lower layers,
        // and make an error page/response
        ->add(ErrorHandlerMiddleware::class)

        // Handle plugin/theme assets like CakePHP normally does.
        ->add(AssetMiddleware::class)

        // Add routing middleware.
        // Routes collection cache enabled by default, to disable route caching
        // pass null as cacheConfig, example: `new RoutingMiddleware($this)`
        // you might want to disable this cache in case your routing is extremely simple
        ->add(new RoutingMiddleware($this, '_cake_routes_'))

        // Add csrf middleware.
        ->add(new CsrfProtectionMiddleware([
            'cookieName' => 'csrf',
            'secure' => true,
            'httpOnly' => true,
        ]));

    return $middlewareQueue;
}

上記がデフォルトの内容となりますが、これから

// Add csrf middleware.
->add(new CsrfProtectionMiddleware([
    'cookieName' => 'csrf',
    'secure' => true,
    'httpOnly' => true,
]));

の部分を削除します。

public function middleware($middlewareQueue)
{
    $middlewareQueue
        // Catch any exceptions in the lower layers,
        // and make an error page/response
        ->add(ErrorHandlerMiddleware::class)

        // Handle plugin/theme assets like CakePHP normally does.
        ->add(AssetMiddleware::class)

        // Add routing middleware.
        // Routes collection cache enabled by default, to disable route caching
        // pass null as cacheConfig, example: `new RoutingMiddleware($this)`
        // you might want to disable this cache in case your routing is extremely simple
        ->add(new RoutingMiddleware($this, '_cake_routes_'));

    return $middlewareQueue;
}

するとこうなる。

/src/Application.php で分岐させても良いけど、Pluginのための分岐なので、
分岐はPlugin側でやる事に。
/plugins/Manage/config/bootstrap.php

ちなみに /plugins/Manage は管理画面用に作成したプラグイン。

plugins/Manage/config/bootstrap.php を更新。

以下の分岐を作成していたので、その中で

use Cake\Event\EventManager;
use Cake\Http\Middleware\CsrfProtectionMiddleware;

$cookieName = 'csrf';
if (!empty($_SERVER['REQUEST_URI']) && preg_match('/^\/manage*/', $_SERVER['REQUEST_URI'])) {
    $cookieName = 'mcsrf';
}

EventManager::instance()->on(
    'Server.buildMiddleware',
    function ($event, \Cake\Http\MiddlewareQueue $middlewareQueue) use ($cookieName) {
        $middlewareQueue->add(new CsrfProtectionMiddleware([
            'cookieName' => $cookieName,
            'secure' => true,
            'httpOnly' => true,
        ]));
    });

のように更新すればOK。

で、確認してたらどうも csrf、mcsrf の両方が登録されてしまう。

何故なんだろうとハマっていたら DebugBar のAjax?で呼んでいる様子。
なので、 DEBUG false にして確認したら無事 /manage 以下では mcsrf だけが利用されており、 /manage と それ以外 で別のクッキー値を参照するようになりましたとさ。

2018年11月20日火曜日

[CakePHP3] セッション(Session)のモデル(テーブル)を通常と特定ディレクトリで分ける方法

SessionのストレージをDatabaseとしている事として以下をメモしています。

管理画面(/manage/*) と その他(/manage/*以外) でセッションデータを保存するDBテーブルを分ける方法。

管理画面(/manage/*) はプラグイン(Plugin)機能を利用して作成。

config/bootstrap.php からプラグインを呼び出す。

Plugin::load('Manage', ['bootstrap' => true, 'routes' => true]);

この時に 'bootstrap' => true を忘れないように。

plugins/Manage/config/bootstrap.php ファイルを作成し、中身は

<?php
use Cake\Core\Configure;

if (!empty($_SERVER['REQUEST_URI']) && preg_match('/^\/manage*/', $_SERVER['REQUEST_URI'])) {
    Configure::write('Session.handler.model','ManageSessions');
    Configure::write('Session.cookiePath','/manage/');
}

DBテーブルは分けるので
デフォルトの sessions と manage_sessions を用意する事を想定する。

CREATE TABLE `sessions` (
  `id` char(40) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
  `created` datetime DEFAULT CURRENT_TIMESTAMP, -- optional, requires MySQL 5.6.5+
  `modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- optional, requires MySQL 5.6.5+
  `data` blob DEFAULT NULL, -- for PostgreSQL use bytea instead of blob
  `expires` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `manage_sessions` (
  `id` char(40) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
  `created` datetime DEFAULT CURRENT_TIMESTAMP, -- optional, requires MySQL 5.6.5+
  `modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- optional, requires MySQL 5.6.5+
  `data` blob DEFAULT NULL, -- for PostgreSQL use bytea instead of blob
  `expires` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2018年11月7日水曜日

[CakePHP3] オリジナルのログイン認証を作成

ちょっとややこしい要件が発生した。

ログインIDが1つでユニークではなく、店舗コード+社員コード という感じで2つのカラムでユニークとなる内容でした。

DBテーブルはこんな感じとする。

table: users
columns: id, shop_id, code, password

table: shops
columns: id, shop_id, code

そして、リクエスト値はこんな感じとする。

code, shop_code, password


やりたいSQLとしては

SELECT *
FROM users
INNER JOIN shops ON users.shop_id = shops.id
WHERE users.code = :code AND shops.code = :shop_code;

で取得してからパスワードチェックするというイメージ。

$this->loadComponent('Auth', [
    'loginAction' => [
        'controller' => 'Users',
        'action' => 'login',
    ],
    'authenticate' => [
        'Form' => [
            'userModel' => 'Users',
            'fields' => [
                'username' => 'username',
                'password' => 'password',
            ],
            'contain' => 'Shops', // 3.1 で非推奨
            'scope' => [], // 3.1 で非推奨
            'finder' => 'login',
        ],
    ],
    'authError' => 'ログインをして、ご利用ください。',
    'loginRedirect' => [
        'controller' => 'Users',
        'action' => 'index'
    ],
    'logoutRedirect' => [
        'controller' => 'Users',
        'action' => 'login'
    ]
]);

って感じでやりたいけど、shop_id を渡せない。。
scope や finder 使ってWHEREに固定した条件を追加する事はできるけど username を追加みたいな事ができない。。

で仕方ないので、オリジナルの Authenticate クラスを作成する事にする。

/src/Auth/UserAuthenticate.php

を作成。

中身は

getTableLocator()->get('Users');

        $user = $userTable->query()
            ->contain(['Shops'])
            ->where([
                'Users.code' => $request->getData('code', ''),
                'Shops.code' => $request->getData('shop_code', ''),
            ])
            ->first();

        $password = $request->getData('password', '');
        if ($this->passwordHasher()->check($password, $user->password)) {
            return $user->toArray();
        }

        return false;
    }
}

作成したら、

$this->loadComponent('Auth', [
    'loginAction' => [
        'controller' => 'Users',
        'action' => 'login',
    ],
    'authenticate' => [
        'Form' => [
            'userModel' => 'Users',
            'fields' => [
                'username' => 'username',
                'password' => 'password',
            ],
            'contain' => 'Shops', // 3.1 で非推奨
            'scope' => [], // 3.1 で非推奨
            'finder' => 'login',
        ],
    ],
    'authError' => 'ログインをして、ご利用ください。',
    'loginRedirect' => [
        'controller' => 'Users',
        'action' => 'index'
    ],
    'logoutRedirect' => [
        'controller' => 'Users',
        'action' => 'login'
    ]
]);

の記述を

$this->loadComponent('Auth', [
    'loginAction' => [
        'controller' => 'Users',
        'action' => 'login',
    ],
    'authenticate' => [
        'User' => [],
    ],
    'authError' => 'ログインをして、ご利用ください。',
    'loginRedirect' => [
        'controller' => 'Users',
        'action' => 'index'
    ],
    'logoutRedirect' => [
        'controller' => 'Users',
        'action' => 'login'
    ]
]);

と修正して完了。

2018年11月6日火曜日

[CakePHP3] パスワードのバリデート (入力 値チェック)

基本的には bake で追加されるメソッド名でのバリデート形式の指定を行うが、正規表現を2回利用したい場合。

$validator
      ->minLength('password', 8, __('6文字以上を入力してください。'))
      ->maxLength('password', 50, __('20文字以下を入力してください。'))
      ->alphaNumeric('password', 'alphaNumeric', __('半角英数字のみ入力可能です。'))
     ->regex('password', '/[a-zA-Z]+/', __('半角英字を1文字以上利用してください。'))
     ->regex('password', '/[0-9]+/', __('半角数字を1文字以上利用してください。'))
      ->requirePresence('password', 'create')
      ->notEmpty('password');

こんな場合は上書きされてしまって、半角英字チェックは動かないので、
こういう場合のみ add で名前を変えて指定するようにして重複を回避する。

$validator
      ->minLength('password', 8, __('6文字以上を入力してください。'))
      ->maxLength('password', 50, __('20文字以下を入力してください。'))
      ->alphaNumeric('password', 'alphaNumeric', __('半角英数字のみ入力可能です。'))
      ->add('password', [
          'inAlpha' => [
              'rule' => ['custom', '/[a-zA-Z]+/'],
              'message' => __('半角英字を1文字以上利用してください。'),
          ],
          'inNumber' => [
              'rule' => ['custom', '/[0-9]+/'],
              'message' => __('半角数字を1文字以上利用してください。'),
          ],
      ])
      ->requirePresence('password', 'create')
      ->notEmpty('password');

  $validator
      ->notEmpty('password_conf')
      ->sameAs('password_conf', 'password', __('異なるパスワードが入力されています。'))
      ->requirePresence('password', 'create')
      ->notEmpty('password');

最初からこの記述を基本にすれば良いと思っていたけどやっぱり bake を基本にした方が効率が良い場面が多いので、
必要な場合のみ利用するようにしました。

regex メソッドの中を見ると解るけど rule としては custom という落とし穴に注意。

[CakePHP3] function _setPassword() が思ったタイミングで動いてくれない

$entity = $this->Samples->get($id);
$entity->password = '12345678';
$this->save($entity);

$entity である

  class Sample extends Entity



  protected function _setPassword($password)

があれば、実行されるのかと思ったいたけどダメでした。。

  $entity->set('password',  '12345678');

でもダメ。。

で、色々試すとここで実行されました。

  $this->Samples->patchEntity($entity, ['password' => '12345678'])

何故この場合だけにしているかは謎ですが、とにかく値を更新する時は必ずこれを利用するようにした方が、
バグが減りそうというメモでした。

2018年11月2日金曜日

[CakePHP3] 文字列型のDBカラムに配列を保存する方法

こんな便利な機能があったとは。。
もっと早く気づきたかった。。

CakePHP3 には文字列カラムに配列をJSON形式などに変換して保存し、取り出し時にまた配列に戻してくれる方法がありました。

_initializeSchema( Cake\Database\Schema\TableSchema $schema )
https://api.cakephp.org/3.6/class-Cake.ORM.Table.html#__initializeSchema

使い方

1.保存したいテーブルの Model にメソッドを追加します。

protected function _initializeSchema(\Cake\Database\Schema\TableSchema $schema)
{
    $schema->setColumnType('categories', 'json');
    return $schema;
}

ここでは カラム名:categories にMultiCheckboxなどで配列で得られる値を JSON形式 で保存する事を想定してみました。

使い方は以上です。

簡単ですね。
今まで知らずに自作してた。。

2018年5月20日日曜日

Cakephp3 でPOST値をGET値で上書き

POST値を更新するなんて場面そう無いだろうけど、一応メモ。

以前は
$this->request->data = $this->request->params;

みたいな書き方でいけてたはずだけど、今はNGみたい。

マニュアルにも無いし、そんな場面作るなよって意味だろうけど以下ならできた。

$params = $this->getRequest()->getQueryParams();
$request = $this->getRequest()->withParsedBody($params);
$this->setRequest($request);


2018/11/06 追記

https://book.cakephp.org/3.0/ja/core-libraries/form.html
このページに「値はリクエストメソッドが GET の時にのみ定義されるべきで、 さもないと正しくないまたは保存されていない直前の POST データを上書きしてしまいます。」
と記載があるので、

  $this->request->withData('name', 'John Doe');
  
を利用するのが良いのかもしれません。。
今は get*** と修正されていっているので、

  $this->getRequest()->withData('name', 'John Doe');

かな。
Symfonyのコンポーネントだけ使ってメールアドレスが正しいかをチェックする

既存システムの改修を行う際にメールアドレスのチェックを強化したいけど、
フレームワークを使ってなかったので、composer で Symfony のバリデーションだけ入れて対応。

まずはコンポーネントを追加
$ composer require symfony/validator
※ 別要件で、 /vendor/autoload.php は読み込み済み。

後は、

http://symfony.com/doc/current/validation.html

を見ながら下の感じで。

use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints\Email;


$validator = Validation::createValidator();
$violations = $validator->validate($email, array(
    new Email(array(
        'message' => 'The email "{{ value }}" is not a valid email.',
        'strict' => true,
        'checkHost' => true,
    )),
));

// エラー有無のチェック
if (0 !== count($violations)) {
 // 有 の場合
 foreach ($violations as $violation) {
    echo $violation->getMessage();
 }
} else {
 // 無 の場合
}

利用可能なオプション

  • strict
  • message
  • checkMX
  • checkHost
  • payload
今回は strict、message、checkHost だけ利用。

2017年6月19日月曜日

fgetcsv で取り込めない問題発生

"能","<p>
あ</p>",""

上記のような3列で1行のSJISのCSVがあった場合、 SJISのロケール追加して、

$ locale -a | grep -i ja
ja_JP
ja_JP.SJIS
ja_JP.eucjp
ja_JP.sjis
ja_JP.ujis
ja_JP.utf8
japanese
japanese.euc
japanese.sjis

という環境であっても、

setlocale(LC_ALL, 'ja_JP.SJIS');

をした後に、fgetcsv() を利用して正常にCSVが取り込むことができない。
別の方法もあった気がしたけど、忘れてしまったのでので今回対応方法をメモ。
考え方としてはiconvコマンドを利用して、SJISファイルをUTF8ファイルに変換してからPHPで取り込むという方法。

exec("iconv -f sjis-win -t utf-8 " . $path . " -o " . $path);
$handle = fopen($path, "r");
$row = fgetcsv($handle, 1024, ',', '"');

2016年5月25日水曜日

CakePHP3 文字数チェックで改行コードがWindowsの時は2文字扱いになる

簡単に予想するからに

環境別改行コード

Windows CR+LF
Macintosh CR
Linux LF

って感じで Windows だけ2バイトになってるからだろう。。
って事で Validation.php を確認すると

public static function maxLength($check, $max)
{
    return mb_strlen($check) <= $max;
}
やっぱり。。 って事で AppController.php(デフォルトでは無い?) の initialize() に
array_walk_recursive($this->request->data, function(&$item, $key){
    // 改行コードをLFに統一
    $item = preg_replace("/\r\n|\r|\n/", "\n", $item);
});
を追加して今回は対応。

2015年3月5日木曜日

PHP fgetcsvを使える環境を構築

fgetcsv にはロケールを指定するパラメータがありません。

そこで fgetcsv を実行する前に

setlocale(LC_ALL, 'ja_JP.SJIS');

を実行する。

が、しかし化ける。。
試しにEUC-JPを指定してみるといけている気がするけど、一部文字で化ける。。
そもそもなんでEUC-JP。。

で、コマンドからサーバーのロケールを確認

$ locale -a | grep JP

ja_JP
ja_JP.eucjp
ja_JP.ujis
ja_JP.utf8

SJISが無い。。
CentOS 6 でも 7でも入ってない。。

って事で追加しよう。

$ localedef -f SHIFT_JIS -i ja_JP /usr/lib/locale/ja_JP.SJIS

をrootで実行して追加、そして確認

$ locale -a | grep JP

ja_JP
ja_JP.SJIS
ja_JP.eucjp
ja_JP.ujis
ja_JP.utf8

そしてfgetcsvの確認。

setlocale(LC_ALL, 'ja_JP.SJIS');
fgetcsv(***);

とても良い感じ♪
SJIS無い、入れれないサーバーだと使えないな。。
しばらくこれで様子を見てみます。

2014年10月28日火曜日

CakePHP2 セットアップ ライブラリ部分のみサブモジュールとして管理

CakePHPのセットアップ

$ git init
$ git pull https://github.com/cakephp/cakephp.git
$ rm -fr .git
$ rm -fr .gitignore
$ rm -fr lib
$ git init
$ git add .
$ git commit -m 'first commit'

$ git submodule add https://github.com/cakephp/cakephp.git
$ git submodule init
$ git submodule update

$ vi app/webroot/index.php
$ vi app/webroot/test.php

//define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'lib');

define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'cakephp' . DS . 'lib');

$ vi app/Console/cake.php

$install = $root . DS . 'lib';

$install = $root . DS . 'cakephp' . DS . 'lib';


$ git add .
$ git commit

$ git remote add origin [repository]
$ git push -u origin master

プラグインの追加

$ git submodule add git://github.com/cakephp/debug_kit.git app/Plugin/DebugKit
$ git submodule add git://github.com/CakeDC/search.git app/Plugin/Search

Followers