PHPプログラムに関する各種メモ書き

PHP 7.4 や 8 で出るエラー「Array and string offset access syntax with curly braces is no longer supported」の修正

次はエラーとなります。

echo $information->img_html_name_{$column_index};

↓ このように修正します

echo $information->{"img_html_name_".$column_index};
No.2480
03/06 15:11

edit

composer で PHPのバージョンを変えて composer install する

開発環境と本番環境でPHPのバージョンが微妙に違うという時に composer パッケージでエラーが出ることがあります。 その時は明示的にPHPのバージョンを教えてあげてからインストールすればOKです

● phpの バージョンを確認する

php -v

● composer に PHPのバージョンを 8.0.16 にセットする命令を送る

composer config platform.php 8.0.16

この後、composer update をすれば指定したPHPバージョンまでのcomposerパッケージがインストールされます

または
composer update
No.2375
07/25 16:19

edit

composer に パッケージを登録する

● バージョンタグをつける

バージョンが 1.2.1 の時の例

git tag v1.2.1
git push origin master
git push origin v1.2.1

● インストールしたパッケージのバージョンを調べる

composer show

● composer のキャッシュをクリアする

composer clear-cache
No.1692
02/11 23:01

edit

PHP で stdClass を 配列に直す

    /**
     * stdClass を 配列に直す
     * @param mixed  $stdClass 
     * @return array  
     */
    protected function stdClassToArray(\stdClass $stdClass)
    {
        $array = json_decode(json_encode($stdClass), true);
        return $array;
    }
No.2202
08/24 14:44

edit

PHPでWEBサーバー(ローカルサーバ)を立ち上げる。ディレクトリ一覧を表示させる

● PHPでビルトインサーバ(ローカルサーバ)を立ち上げる

-S : ポート番号を指定
-t : ドキュメントルートにするディレクトリ

php -S 0.0.0.0:8000 -t dist

これで http://localhost/ または http://ローカルIPアドレス/ で表示できます。

● PHPでビルトインサーバ(ローカルサーバ)を立ち上げ、(index.htmlがない場合に)ディレクトリ一覧を表示させる

php -S 0.0.0.0:8000 -t html html/_route.php

ファイル名 _route.php でドキュメントルートに保存

<?php
$f = preg_replace('/\/$/', '', __DIR__ . "{$_SERVER['REQUEST_URI']}");
if (is_dir($f)) {
	$abf = preg_replace('/\/$/', '', $_SERVER['REQUEST_URI']);
	$fs = glob("$f/*", GLOB_MARK);
	foreach ($fs as $v) {

		$v = str_replace($f . '/', '', $v);
		echo "<a href='$abf/$v'>$v</a><br/>";
	}
	return true;
} else {
	return false;
}

これでindex.htmlがない場合にディレクトリ一覧が表示されます。

● MacでのPHPビルトインサーバ起動スクリプト

Macの場合次のようにブラウザを自動立ち上げにしておくと楽です

例 : server_start.sh

local_ip=`ipconfig getifaddr en0`
open "http://$local_ip:8000/"
php -S 0.0.0.0:8000 -t httpdocs
No.1385
05/04 10:49

edit

amphp/amp を使って PHP7 で非同期(並列)処理

PHP8.1からは Fibers を使って非同期処理を記述することができますが
PHP 7でも amphp/amp を使う事でとても簡単に非同期処理を記述・実行することができます。

● 1. amphp/ampのインストール

composer require amphp/amp
composer require amphp/parallel-functions

● 2. 非同期処理の記述

例として3つのWEBサイトへ非同期でアクセスして、取得したhtmlのバイト数を返すプログラムを書いてみます

test.php

<?php

require_once './vendor/autoload.php';

use function Amp\ParallelFunctions\parallelMap;
use function Amp\Promise\wait;

function testFunc()
{
  $responses = wait(parallelMap([
      'https://stackoverflow.com/',
      'https://google.com/',
      'https://github.com/',
  ], function ($url) {
    $options = stream_context_create(array('ssl' => array(
      'verify_peer'      => false,
      'verify_peer_name' => false
    )));
    return file_get_contents($url, false, $options);
  }));

  echo strlen($responses[0]) . "\n";
  echo strlen($responses[1]) . "\n";
  echo strlen($responses[2]) . "\n";
}

function format_microtime ( $time, $format = null )
{
  if (is_string($format)) {
    $sec  = (int)$time;
    $msec = (int)(($time - $sec) * 100000);
    $formated = date($format, $sec). '.'. $msec;
  } else {
    $formated = sprintf('%0.5f', $time);
  }
  return $formated;
}



$start_time = microtime(true);

// 処理の実行
testFunc();

$end_time        = microtime(true);
$processing_time = $end_time - $start_time;
echo "処理時間:".format_microtime($processing_time)."秒\n";

● 3. 同じ処理を非同期を使わずに記述してみる

<?php

require_once './vendor/autoload.php';

function testFunc()
{
  $options = stream_context_create(array('ssl' => array(
    'verify_peer'      => false,
    'verify_peer_name' => false
  )));
   
  $responses[] = file_get_contents('https://stackoverflow.com/', false, $options);
  $responses[] = file_get_contents('https://google.com/', false, $options);
  $responses[] = file_get_contents('https://github.com/', false, $options);

  echo strlen($responses[0]) . "\n";
  echo strlen($responses[1]) . "\n";
  echo strlen($responses[2]) . "\n";
}

function format_microtime ( $time, $format = null )
{
  if (is_string($format)) {
    $sec  = (int)$time;
    $msec = (int)(($time - $sec) * 100000);
    $formated = date($format, $sec). '.'. $msec;
  } else {
    $formated = sprintf('%0.5f', $time);
  }
  return $formated;
}



$start_time = microtime(true);

// 処理の実行
testFunc();

$end_time        = microtime(true);
$processing_time = $end_time - $start_time;

echo "処理時間:".format_microtime($processing_time)."秒\n";

● 4. 実行して比較する

 php test.php 

結果例

180126
51223
279741
処理時間:1.07782秒

● 4. 比較する

それぞれ10回ずつ実行した結果はこちらになります

ampを使った非同期実行
処理時間:0.89127秒
処理時間:0.84902秒
処理時間:1.52270秒
処理時間:1.29796秒
処理時間:1.51700秒
処理時間:0.99289秒
処理時間:0.97136秒
処理時間:0.83685秒
処理時間:0.86408秒
処理時間:1.06043秒

平均は 1.08 sec
(0.89127+0.84902+1.52270+1.29796+1.51700+0.99289+0.97136+0.83685+0.86408+1.06043)/10





非同期を使わず実行
処理時間:1.62977秒
処理時間:1.55046秒
処理時間:1.56966秒
処理時間:1.76191秒
処理時間:1.55104秒
処理時間:1.69673秒
処理時間:1.74086秒
処理時間:1.57090秒
処理時間:1.69566秒
処理時間:1.65347秒

平均は : 1.64 sec (1.62977+1.55046+1.56966+1.76191+1.55104+1.69673+1.74086+1.57090+1.69566+1.65347)/10

● 注意点 WEBアプリで使用する場合は子プロセス生成に失敗します

(ウェブサーバーの設定権限によりけりだとは思いますが、WEBサーバから実行されたPHPの場合はうまく子プロセスが起動できずエラーとなります。)

No.2109
12/08 16:23

edit

PHP 7.4 で Twig を使用すると自動的に改行やスペースが削除されてしまう不具合に対応する

● PHP 7.4 で Twig を使用すると自動的に改行やスペースが削除されてしまう不具合に対応する

Lexer.php:163 を以下のように修正します

if (isset($this->positions[2][$this->position][0]) ) {
    $text = rtrim($text);
}

    ↓

if (isset($this->positions[2][$this->position][0]) && ($this->options['whitespace_trim'] === $this->positions[2][$this->position][0])) {
   $text = rtrim($text);
}
No.2037
09/10 15:23

edit

Twig

PHPで isNullOrEmpty() メソッド

● PHPで isNullOrEmpty() メソッド

if ( strlen(@$str) == 0 ){
    //your code here
}
No.1983
06/28 12:23

edit

PHPで2つのテキストの差分をとる

● jfcherng/php-diff

composer require jfcherng/php-diff

● 差分を取る

$old = 'This is the old string.';
$new = 'And this is the new one.';
$result = \Jfcherng\Diff\DiffHelper::calculate($old, $new, 'Unified'); // Context, JsonText, Unified
var_dump( $result );
No.1970
03/12 20:35

edit

composer2 を使用する

● 現在のcomposerのバージョンをチェックする

composer --version

このように返ってくる場合はバージョン1を使用しています。 バージョン2にアップデートしましょう

Composer version 1.10.9 2020-07-16 12:57:00

● Composer Version 2にアップデートする

composer self-update

● 次のようにエラーが表示されることがあります

  Composer update failed: "/usr/local/bin/composer" could not be written.                               
  rename(/home/myuser/.cache/composer/composer-temp.phar,/usr/local/bin/composer): Permission denied 

root ユーザーから /usr/local/bin のパーミッションを変更します。

ls -la /usr/local/

( /usr/local/bin の権限を確認しておく )

/usr/local/bin/ の権限を 0777 にします。(あとで戻します)

sudo chmod 0777 /usr/local/bin/
composer self-update
composer --version

Version2 になったことを確認します。

Composer version 2.0.2 2020-10-25 23:03:59

/usr/local/bin/ の権限を 0755 に戻します

sudo chmod 0755 /usr/local/bin/
ls -la /usr/local/

● エラーが出る場合は composer の 再インストールを行います

SHA384 is not supported by your openssl extension, could not verify the phar file integrity 

↑ 。エラーメッセージが出る場合はいちど削除して再度インストールします(rootユーザーで行います。)

sudo rm -rf /usr/local/bin/composer
sudo curl -s https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
No.1889
09/03 14:26

edit

vs code で入力を補助できるPHPDocの書き方

● PHPDocの書き方

/**
 * このメソッドはXXを行います
 *
 * 詳細1
 * 詳細2
 *
 * @param   int         $id
 * @param   string      $name
 * @param   array       $hash
 *
 * @return \App\Models\User | \App\Models\User[]
 *
 * @todo    
 * @test    
 */
No.1859
02/06 15:54

edit

PHP で数字以外の文字列を int 型にキャストする

● PHP で数字以外の文字列を int 型にキャストする

echo (int)"OK"; 

結果は

0

になります。

No.1847
08/28 10:18

edit

PHPの Swift Mailer で stream_socket_enable_crypto(): SSL operation failed with code 1 が出る時の対処法

● PHPの Swift Mailer で stream_socket_enable_crypto(): SSL operation failed with code 1 が出る時の対処法

setStreamOptionsverify_peer を false にすればとりあえずはOKです。(応急処置)

$transport = Swift_SmtpTransport::newInstance('smtp.server.com', 123, 'tls')
    ->setUsername('username')
    ->setPassword('password')
    ->setStreamOptions(array('ssl' => array('allow_self_signed' => true, 'verify_peer' => false)));

これでOKです。( setStreamOptions の行を追加 )

これはどういうことかというと、ソケット通信を行うときに以下のオプションを設定するということです

$options['ssl']['verify_peer'] = FALSE;
$options['ssl']['verify_peer_name'] = FALSE;
No.1838
08/17 11:57

edit

guzzle を使った URL 存在チェック

● guzzle を使った URL 存在チェック

ただし、楽天のようにリダイレクトしている場合はコンテンツを取得して redirect があるかどうかをチェックする必要があります。

	/**
	 * URLの存在チェック
	 *
	 */
	public function check_url_exists( string $url )
	{
		// $url = "https://item.rakuten.co.jp/iloiloislandimport/rb084myjgdf/?201604";
		$url = "https://item.rakuten.co.jp/iloiloislandimport/rb01m63hrzm/?832467";
	    $client = new GuzzleHttp\Client();
	    try {
	        $request = $client->head($url);
	        $this->mydump->dump( $request->getStatusCode()  );
	        $this->mydump->dump( "OK URL exists : {$url}" );
	        return true;
	    } catch (GuzzleHttp\Exception\ClientException $e) {
	        return false;
	        $this->mydump->dump( "NG URL not exists : {$url}" );
	    }
	}
No.1828
08/01 00:28

edit

フレームワークを使用していない素のPHPでCSRFトークン認証を行う

● volnix/csrf

https://packagist.org/packages/volnix/csrf

composer require volnix/csrf

● CSRFトークンの発行

<form action="index.php" method="post">
	<input type="hidden" name="<?= \Volnix\CSRF\CSRF::TOKEN_NAME ?>" value="<?= \Volnix\CSRF\CSRF::getToken() ?>"/>
	<input type="text" name="action" placeholder="Enter an action."/>
	<input type="submit" value="Submit" name="sub"/>
</form>

● CSRFトークンの認証

// generic POST data
if ( CSRF::validate($_POST) ) {
	// good token
} else {
	// bad token
}
No.1813
07/09 09:10

edit

PHP で null と 0 を判別する

● ○ if (is_null( $a) )で判別する

● × (int)$a は $a が null の時0 になるので判別できません。

No.1781
06/10 22:58

edit

三項演算子の省略記法(エルビス演算子)を使ってコードを短くする

● 三項演算子の省略記法(エルビス演算子)を使ってコードを短くする例

// SQL で ソートするときのDBカラムと並び順のデフォルト
$column    = 'id';
$direction = 'DESC';

// $setting_order_column, $setting_order_direction に値が入っているときはそっちの値を優先
if ( isset($setting_order_column) ){
	$column    = $setting_order_column;
}
if ( isset($setting_order_direction) ){
	$direction    = $setting_order_direction;
}

 ↓

エルビス演算子)を使って 2行で書けます。

$column    = @$setting_order_column ?: 'id';
$direction = @$setting_order_direction ?: 'DESC';
No.1721
03/20 09:10

edit

PHP 拡張 gRPC をインストールする

● PHP API のバージョンを調べる

php -i | grep API

表示例

PHP API => 20180731

● pecl コマンドに PHPのバージョンを教える

現在のpeclの「phpパス設定」を調べる

pecl config-get php_bin

これがお使いのphpと違う場合はセットします。

pecl config-set php_bin /usr/local/bin/php

● PHP 拡張 gRPC を pecl コマンドからインストールする

https://grpc.io/docs/quickstart/php/

sudo pecl install grpc

インストールする .so ライブラリのフルパスが表示されます

Installing '/usr/lib64/php/modules/grpc.so'

● php.iniの場所を確認し編集する

php -r "echo phpinfo();" | grep "php.ini"
vi /etc/php7.d/php.ini
extension=/usr/lib64/php/modules/grpc.so

を追加する。

● composer から gRPC をインストールする

composer require "grpc/grpc:^v1.1.0"
No.1653
01/15 17:28

edit

composer が メモリ不足で強制終了となるのに対処する

● composer が メモリ不足で強制終了となるのに対処する

現在のswapファイルを確認します

swapon -s 

root アカウントから swapファイルを作成します。( 2GB のスワップファイルを作成します )

free -m
mkdir -p /var/_swap_
cd /var/_swap_
# 2GB of swap memory
dd if=/dev/zero of=swapfile bs=1M count=2048
mkswap swapfile
swapon swapfile
chmod 600 swapfile
echo "/var/_swap_/swapfile none swap sw 0 0" >> /etc/fstab
#cat /proc/meminfo
free -m

この後にcomposer コマンドを実行します。

● 作成した swapfile を削除する

作成した swapfile を削除したい時は次のコマンドを実行します。

swapoff /var/_swap_/swapfile
rm /var/_swap_/swapfile

引用: http://bit.ly/2Q26CPH

● swapfile を作成しても composer が Allowed memory size of xxxxx bytes exhausted エラーで終了する場合の対処方法

例:composer update を実行する場合

composer update

  ↓ 「composer」コマンドを「php -d memory_limit=-1 /usr/local/bin/composer」に変更します

php -d memory_limit=-1 /usr/local/bin/composer update

何度も打つのが面倒な場合は .bash_profile にエイリアス登録しておきます。

alias composer='php -d memory_limit=-1 /usr/local/bin/composer'
No.1647
12/29 13:52

edit

PHPで自分のIPアドレスを取得する

● PHPで自分のIPアドレスを取得する

$localIP = getHostByName(getHostName());
No.1642
12/18 14:18

edit

PHP で PDFからテキストなどのデータを取り出す

PHP で PDFからテキストなどのデータを取り出すには pdfparser を使用します。

● smalot/pdfparser

composer require smalot/pdfparser

次のようなコードで PDF から必要な情報を取り出すことができます。

<?php
use Spatie\PdfToText\Pdf;
require_once __DIR__ . '/vendor/autoload.php';

$parser = new \Smalot\PdfParser\Parser();
$pdf    = $parser->parseFile('test.pdf');

var_dump( $pdf->getText() );
var_dump( $pdf->getDetails() );
var_dump( $pdf->getTrailer() );
var_dump( $pdf->getObjects() );

var_dump( $pdf->getFonts() );

foreach ($pdf->getObjects() as $k => $v) {
	echo "\n\n=====\n" . $k ."\n=====\n";
	echo "Type:" . $v->get('Type') . "\n";
	echo "Details:"; print_r($v->getDetails());
}
No.1636
12/04 10:09

edit

PHP の スタンダードなメール送信モジュール Swift_Mailer を使ってメールを送信する

● 1. メール送信方式(transport)を選んで作成する

(選択できるメール送信方式)

  • SMTPサーバを使う ( Swift_SmtpTransport )(おすすめ)
  • sendmailコマンドを使う ( Swift_SendmailTransport )

・1-1. SMTPサーバを使う

$SMTP_host = 'smtp.YOUR-SERVER.com';
$SMTP_port = '587';
$SMTP_option = 'tls';
$SMTP_user = '<メールアドレス>';
$SMTP_pass = '<メールパスワード>';	// Gmailの場合は2段階認証をon にしてアプリパスワードを設定します。

$transport = (new Swift_SmtpTransport($SMTP_host, $SMTP_port, $SMTP_option))
    ->setUsername($SMTP_user)
    ->setPassword($SMTP_pass);

・1-2. sendmailコマンドを使う

$transport = new Swift_SendmailTransport('/usr/sbin/sendmail -t');

● 2. メッセージを作成する

$mailer = new Swift_Mailer($transport);

$message = (new \Swift_Message('My important subject here'))
    ->setFrom([$from => $from_name])
    ->setTo( $to )
    ->setSubject( $subject )
    ->setBody( $mailtext);    // , 'text/html'

● 3. メッセージを送信する

$result = $mailer->send($message);
No.1629
11/27 11:06

edit

composer で zipファイルが解凍出来ないエラーの対処法

● composer でインストール時に zipファイルが解凍出来ないエラーの対処法

次のようなエラーが表示されることがあります

  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
unzip:  cannot find zipfile directory in one of /YOUR/SERVER/PATH/guzzlehttp/psr7/e765a36a8974402d69059b78fed51f3e or .....

● composerの キャッシュをクリアにして解決

composer clearcache
No.1619
11/11 12:41

edit

composer で 自作パッケージを使用する / トークンエラーに対応する

● composer で 自作パッケージを使用する

● 次のコマンドを実行できる自作パッケージを composer で管理する

use Hogehoge\HelloComposer;
HelloComposer\HelloComposer::show('テストの文字列です');

● 1. Github に 次のファイル構成でファイルを push

hogehoge
|--hellocomposer
|  |--README.md
|  |--composer.json
|  |--src
|  |  |--HelloComposer.php

HelloComposer.php の 中

<?php

namespace Hogehoge\HelloComposer;

class HelloComposer
{
    public static function show( $message='hello !' )
    {
    	echo $message;
    }
}

composer.json の 中

{
    "name": "hogehoge/hellocomposer",
    "description": "hello-composer",
    "type": "library",
    "minimum-stability": "stable" ,
	"require": {
		"php": ">=7.0.0"
	},
	"autoload": {
		"psr-4": {
			"Hogehoge\\HelloComposer\\": "src/"
		}
	}
}

psr-4 のところだけ 名前空間を記述するので、

・先頭文字大文字
・区切りはバックスラッシュ( "" の中にあるのでエスケープするように2個連続 )

で記述します。 それ以外は小文字で記述します。

● 2. 読み込む側の ディレクトリのトップの composer.json に以下の項目を追加する

1.repositories を追加する

    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/hogehoge/hellocomposer.git"
        }
    ],

hogehoge/hellocomposer.git のところは適宜書き換えてください)

2.require を追加する

    "require": {
        ..............................
        "hogehoge/hellocomposer" : "dev-master"
    },

hogehoge/hellocomposer のところは適宜書き換えてください)

● 3. composer コマンドで読み込み、名前空間のファイルを生成する

composer update
composer dump-autoload

composer dump-autoload は必ず update のたびに実行しましょう。

これで準備が整いました。

use Hogehoge\HelloComposer;
HelloComposer\HelloComposer::show('テストの文字列です');

こちらが使用できます。

● GitHub API limit (60 calls/hr) エラーが出る場合の対応

curl -u 'アカウント名' -d '{"scopes":["repo"],"note":"Help example"}' https://api.github.com/authorizations

パスワードを聞かれるので入れます。 成功すると json が帰ってくるので、その中の

  "token": "aa482378bbe99729923d5cf7xxxxxxxxxxxxxxxx",

のような文字列を保存

composer config -g github-oauth.github.com aa482378bbe99729923d5cf7xxxxxxxxxxxxxxxx

のようにコマンドを打てばOKです。

● 上記コマンドで「"code": "already_exists"」エラーとなる場合

GithubへWEBサイトからログインし、

Settings → Developer settings →Personal access tokens

メニューから既存のトークンを削除します。

または Help example の文字列を変えて再度コマンドを実行します。

No.1617
03/25 09:52

edit

Laravel や composer コマンドで 「PHP Warning: proc_open(): fork failed 」エラーとなるときの対処法

● Laravel や composer コマンドで 「PHP Warning: proc_open(): fork failed 」エラーとなるときの対処法

調べたところ、EC2 の micro インスタンスだとかなりの高確率でなるようです。

PHP Warning:  proc_open(): fork failed - Cannot allocate memory in phar:///usr/bin/composer/vendor/symfony/console/Application.php on line 952

**root*ユーザーから次の3つのコマンドを実行します

/bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024
/sbin/mkswap /var/swap.1
/sbin/swapon /var/swap.1

その後再度先ほど実行できなかったコマンドを再実行すると動きます!

No.1614
11/06 09:12

edit

PHP の DOMオブジェクトを扱う

PHPでも JavaScript のように、html文書からDOMオブジェクトを扱いたい時があります。

● PHP の DOMオブジェクトを扱う

html例

<table id="my_id" data-height="999">
<tr>
<td>テストテーブル</td>
</tr>
</table>

phpでDOMを扱う

$dom = new \DomDocument();
libxml_use_internal_errors( true );  // html構造のエラーで止めたくない場合はこの行を有効にしてエラー抑制

// Domに喰わせるために html,body タグを追加する
$content_with_html_body = '<html><body>'.$content.'</body></html>';
$dom->loadHtml(mb_convert_encoding($content_with_html_body, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
libxml_clear_errors();  //  // html構造のエラーで止めたくない場合はこの行を有効にしてエラー抑制

// id = "my_id" を取得
$top_table = $dom->getElementById('my_id');
dump( $top_table);
dump( $top_table->ownerDocument->saveHTML() );  // 取得したdomオブジェクトのhtmlを確認する
dump( $top_table->getAttribute('data-height') );    // 取得したdomオブジェクトの data-height = 999 を取得
No.1611
11/01 09:52

edit

DOMDocument::loadHTML(): Unexpected end tag エラーを無視する

● DOMDocument::loadHTML(): Unexpected end tag エラーを無視する

$html = '<html><body><p><img src="aaa.jpg"></body></html>';
$dom = new \DOMDocument();
libxml_use_internal_errors( true );  // ここを追加
$dom->loadHTML( $html );
libxml_clear_errors();  // ここを追加
var_dump( $dom->getElementsByTagName( "video" )->length );

引用: http://bit.ly/33iq0wn

● libxml_use_internal_errors() の使い方

true が渡されたときユーザによるエラー処理を有効にする

libxml_use_internal_errors( true );
$doc = new DOMDocument;
if (!$doc->load('file.xml')) {
    foreach (libxml_get_errors() as $error) {
        // ここでエラー処理をします
    }
    libxml_clear_errors();
}
No.1569
08/07 23:07

edit

PHPで大量のデータを登録するときの制限(max_input_vars)を php.ini で増やす

● php.ini max_input_vars の数を確認する

 cat /etc/php7.d/php.ini | grep max_input_vars
; max_input_vars

max_input_vars がコメントアウトされている場合は デフォルト値の1000がセットされるので、 大量データを処理するときには少なすぎて危険です。

増やしておきましょう

max_input_vars = 99999
No.1554
07/17 21:18

edit

php.ini の 場所を調べる

● php.ini の 場所を調べる

こちらのコマンドで php.ini の場所を表示させる事ができます。

php -r "echo phpinfo();" | grep "php.ini"
No.1529
06/11 11:21

edit

PHPの正規表現検索 preg_match で変数を使う

preg_match で変数を使うにはpreg_quoteを使用します。

string preg_quote ( string $str [, string $delimiter = NULL ] )
$file = 'my_file_123456789';
$needle = 'my_file_'

$pattern = '/' . preg_quote($needle, '/') . '/';
if ( preg_match($pattern, $file) ){
	echo 'マッチします。';
}
No.1017
05/18 13:01

edit

正規表現

PHPのCarbonで日本語の曜日を表示させる

● php.ini の default_locale 設定を確認する

echo setlocale(LC_ALL, 0);

何も設定されてない場合

C

日本語に設定されている場合

LC_CTYPE=ja_JP.UTF-8;LC_NUMERIC=C;LC_TIME=C;LC_COLLATE=C;LC_MONETARY=C;LC_MESSAGES=C;LC_PAPER=C;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=C;LC_IDENTIFICATION=C

● php.ini の default_locale を設定する

デフォルトロケールを設定する

cat /etc/php7.d/php.ini | grep locale
vi /etc/php7.d/php.ini
intl.default_locale =ja_JP.UTF-8

● Carbonで曜日をデフォルト言語で表示させる

$dt = new \Carbon\Carbon();
echo $dt->formatLocalized('%a');

● Carbonで曜日を日本語で表示させる

明示的にロケールを指定します

setlocale(LC_ALL, 'ja_JP.UTF-8');
$dt = new \Carbon\Carbon();
echo $dt->formatLocalized('%a');
No.1519
05/29 14:42

edit

PHPのヒアドキュメント比較

● PHPのヒアドキュメント(画面上に表示)

print <<< DOC_END
ここに内容を記述
ここに内容を記述
ここに内容を記述
DOC_END;

● PHPのヒアドキュメント(変数$textに代入)

$text = <<< DOC_END
ここに内容を記述
ここに内容を記述
ここに内容を記述
DOC_END;

● PHPのヒアドキュメント(変数 $hoge を展開する)

$hoge = 'ほげほげ';
print <<< DOC_END
ここに内容を記述
$hoge
ここに内容を記述
DOC_END;

● PHPのヒアドキュメント(変数 $hoge を展開しない)

$hoge = 'ほげほげ';
print <<< 'DOC_END'
ここに内容を記述
$hoge
ここに内容を記述
DOC_END;
No.636
05/07 12:57

edit

PHPで中国語かどうかを判別する

● Unihan.zip を取得

https://www.unicode.org/Public/UCD/latest/ucd/Unihan.zip

この中の Unihan_Variants.txt を見てみます。

U+343D	kTraditionalVariant	U+5051

がありますが、これは

(コードポイント : U+343D)は(コードポイント: U+5051)の簡体字ですよ

という意味だそうです。

こちらのサイト
Unicodeの一覧ツール
を使って何文字か変換してみると

簡体字 繁体字
㐽(コードポイント : U+343D) 偑(コードポイント: U+5051)
㑇(コードポイント : U+3447) 㑳(コードポイント: U+3473)
㑈(コードポイント : U+3448) 倲(コードポイント: U+5032)
㑔(コードポイント : U+3454) 㑯(コードポイント: U+346F)

という表になります。(多分あっている・・・はずです。)

● Unihan_Variants.txt から 中国語の繁体字、簡体字のコードポイントのリストを作成

list.txt にリストを保存します。

・簡体字のリストを作成

cat Unihan_Variants.txt | grep kTraditionalVariant | sed s/kTraditionalVariant.*// | sed s/$'\t'//g | sed s/$'^U+'//g > kantai.list

・繁体字のリストを作成

cat Unihan_Variants.txt | grep kSimplifiedVariant | sed s/kSimplifiedVariant.*// | sed s/$'\t'//g | sed s/$'^U+'//g > hantai.list

● PHP の preg_match で Unicode Codepoint でマッチさせる

例えば漢字の「あ」は

http://unicode.scarfboy.com/?s=U+3042

U+3042

です。

PHPでマッチさせるには

$test = 'あいうえお';
if ( preg_match('/(\x{3042})/u', $test, $r) ){
	echo 'マッチしました。';
	var_dump($r);
} 

のように記述します。

● ある文字列が中国語の繁体字、簡体字を持つ場合中国語と判定する

先ほどのリストを使って簡体字、繁体字の正規表現を作成してマッチするかどうか判別します。 ただし日本語で使用する漢字のみの場合も中国語としてマッチします。

$test_array = [
	'比特币',
	'以创纪录的水平扩容并将保持继续' ,
	'あいうえお' ,
	'細野晴臣' ,
	'今日はとても暖かい1日となりました' ,
	'日本語のテストを行っています。' ,
];

foreach ($test_array as $v) {
	echo '================' .$v."\n";
 	if ( hasHiragana($v) ){ echo 'ひらがなを含みます。'; }
 	if ( hasKatakana($v) ){ echo 'カタカナを含みます。'; }
 	if ( hasKanji($v) ){ echo '漢字を含みます。'; }
	if ( hasKantaiji($v) ){ echo '簡体字を含みます。'; }
	if ( hasHantaiji($v) ){ echo '繁体字を含みます。'; }
	echo "\n\n";	   
}
function hasKantaiji(string $input)
{
	if ( preg_match('/(\x{343D}|\x{3447}|\x{3448}|\x{3454}|\x{3469}|\x{34E5}|\x{3509}|\x{358A}|\x{359E}|\x{360E}|\x{36AF}|\x{36C0}|\x{36DF}|\x{36E0}|\x{36E3}|\x{36E4}|\x{36FF}|\x{37C6}|\x{37DC}|\x{3918}|\x{39CF}|\x{39D0}|\x{39D1}|\x{39DF}|\x{39F0}|\x{3A2B}|\x{3B4E}|\x{3B4F}|\x{3B63}|\x{3B64}|\x{3B74}|\x{3C69}|\x{3C6E}|\x{3CBF}|\x{3CD4}|\x{3CD5}|\x{3CE0}|\x{3CE1}|\x{3CE2}|\x{3CFD}|\x{3D89}|\x{3DB6}|\x{3DBD}|\x{3E8D}|\x{3EC5}|\x{3ECF}|\x{3ED8}|\x{4025}|\x{4056}|\x{40B5}|\x{4149}|\x{416A}|\x{41F2}|\x{4264}|\x{4336}|\x{4337}|\x{4338}|\x{4339}|\x{433A}|\x{433B}|\x{433C}|\x{433D}|\x{433E}|\x{4340}|\x{4341}|\x{44D5}|\x{45D6}|\x{461B}|\x{461E}|\x{464A}|\x{464C}|\x{4653}|\x{4723}|\x{4724}|\x{4725}|\x{4727}|\x{4729}|\x{4759}|\x{478C}|\x{478D}|\x{478E}|\x{4790}|\x{47E2}|\x{4880}|\x{4881}|\x{4882}|\x{497A}|\x{497D}|\x{497E}|\x{497F}|\x{4980}|\x{4981}|\x{4982}|\x{4983}|\x{4985}|\x{49B6}|\x{49B7}|\x{4B6A}|\x{4BC3}|\x{4BC4}|\x{4BC5}|\x{4C9D}|\x{4C9E}|\x{4C9F}|\x{4CA0}|\x{4CA1}|\x{4CA2}|\x{4CA3}|\x{4CA4}|\x{4D13}|\x{4D14}|\x{4D15}|\x{4D16}|\x{4D17}|\x{4D18}|\x{4D19}|\x{4DAE}|\x{4E07}|\x{4E0E}|\x{4E11}|\x{4E13}|\x{4E1A}|\x{4E1B}|\x{4E1C}|\x{4E1D}|\x{4E22}|\x{4E24}|\x{4E25}|\x{4E27}|\x{4E2A}|\x{4E30}|\x{4E34}|\x{4E3A}|\x{4E3D}|\x{4E3E}|\x{4E48}|\x{4E49}|\x{4E4C}|\x{4E50}|\x{4E54}|\x{4E60}|\x{4E61}|\x{4E66}|\x{4E70}|\x{4E71}|\x{4E89}|\x{4E8E}|\x{4E8F}|\x{4E91}|\x{4E9A}|\x{4EA7}|\x{4EA9}|\x{4EB2}|\x{4EB5}|\x{4EB8}|\x{4EBF}|\x{4EC5}|\x{4EC6}|\x{4ECE}|\x{4ED1}|\x{4ED3}|\x{4EEA}|\x{4EEC}|\x{4EF7}|\x{4F17}|\x{4F18}|\x{4F1A}|\x{4F1B}|\x{4F1E}|\x{4F1F}|\x{4F20}|\x{4F21}|\x{4F23}|\x{4F24}|\x{4F25}|\x{4F26}|\x{4F27}|\x{4F2A}|\x{4F2B}|\x{4F53}|\x{4F59}|\x{4F63}|\x{4F65}|\x{4FA0}|\x{4FA3}|\x{4FA5}|\x{4FA6}|\x{4FA7}|\x{4FA8}|\x{4FA9}|\x{4FAA}|\x{4FAC}|\x{4FE3}|\x{4FE6}|\x{4FE8}|\x{4FE9}|\x{4FEA}|\x{4FEB}|\x{4FED}|\x{503A}|\x{503E}|\x{506C}|\x{507B}|\x{507E}|\x{507F}|\x{50A5}|\x{50A7}|\x{50A8}|\x{50A9}|\x{513F}|\x{514B}|\x{5151}|\x{5156}|\x{515A}|\x{5170}|\x{5173}|\x{5174}|\x{5179}|\x{517B}|\x{517D}|\x{5181}|\x{5185}|\x{5188}|\x{518C}|\x{5199}|\x{519B}|\x{519C}|\x{51AF}|\x{51B2}|\x{51B3}|\x{51B5}|\x{51BB}|\x{51C0}|\x{51C6}|\x{51C9}|\x{51CF}|\x{51D1}|\x{51DB}|\x{51E0}|\x{51E4}|\x{51EB}|\x{51ED}|\x{51EF}|\x{51FB}|\x{51FF}|\x{520D}|\x{5212}|\x{5218}|\x{5219}|\x{521A}|\x{521B}|\x{5220}|\x{522B}|\x{522C}|\x{522D}|\x{522E}|\x{5236}|\x{5239}|\x{523D}|\x{523E}|\x{523F}|\x{5240}|\x{5242}|\x{5250}|\x{5251}|\x{5265}|\x{5267}|\x{529D}|\x{529E}|\x{52A1}|\x{52A2}|\x{52A8}|\x{52B1}|\x{52B2}|\x{52B3}|\x{52BF}|\x{52CB}|\x{52DA}|\x{5300}|\x{5326}|\x{532E}|\x{533A}|\x{533B}|\x{534E}|\x{534F}|\x{5355}|\x{5356}|\x{5362}|\x{5364}|\x{536B}|\x{5374}|\x{5382}|\x{5385}|\x{5386}|\x{5389}|\x{538B}|\x{538C}|\x{538D}|\x{5390}|\x{5395}|\x{5398}|\x{53A2}|\x{53A3}|\x{53A6}|\x{53A8}|\x{53A9}|\x{53AE}|\x{53BF}|\x{53C1}|\x{53C2}|\x{53CC}|\x{53D1}|\x{53D8}|\x{53D9}|\x{53E0}|\x{53EA}|\x{53F0}|\x{53F6}|\x{53F7}|\x{53F9}|\x{53FD}|\x{540C}|\x{540E}|\x{5411}|\x{5413}|\x{5415}|\x{5417}|\x{5423}|\x{5428}|\x{542C}|\x{542F}|\x{5434}|\x{5450}|\x{5452}|\x{5453}|\x{5455}|\x{5456}|\x{5457}|\x{5458}|\x{5459}|\x{545B}|\x{545C}|\x{548F}|\x{5499}|\x{549B}|\x{549D}|\x{54A4}|\x{54B8}|\x{54CD}|\x{54D1}|\x{54D2}|\x{54D3}|\x{54D4}|\x{54D5}|\x{54D7}|\x{54D9}|\x{54DC}|\x{54DD}|\x{54DF}|\x{551B}|\x{551D}|\x{5520}|\x{5521}|\x{5522}|\x{5524}|\x{5567}|\x{556C}|\x{556D}|\x{556E}|\x{556F}|\x{5570}|\x{5574}|\x{5578}|\x{55B7}|\x{55BD}|\x{55BE}|\x{55EB}|\x{55F3}|\x{5618}|\x{5624}|\x{5631}|\x{565C}|\x{56A3}|\x{56E2}|\x{56ED}|\x{56F0}|\x{56F1}|\x{56F4}|\x{56F5}|\x{56FD}|\x{56FE}|\x{5706}|\x{5723}|\x{5739}|\x{573A}|\x{5742}|\x{574F}|\x{5757}|\x{575A}|\x{575B}|\x{575C}|\x{575D}|\x{575E}|\x{575F}|\x{5760}|\x{5784}|\x{5785}|\x{5786}|\x{5792}|\x{57A6}|\x{57A9}|\x{57AB}|\x{57AD}|\x{57B1}|\x{57B2}|\x{57B4}|\x{57D8}|\x{57D9}|\x{57DA}|\x{57EF}|\x{5811}|\x{5815}|\x{5899}|\x{58EE}|\x{58F0}|\x{58F3}|\x{58F6}|\x{58F8}|\x{5904}|\x{5907}|\x{590D}|\x{591F}|\x{5934}|\x{5938}|\x{5939}|\x{593A}|\x{5941}|\x{5942}|\x{594B}|\x{5956}|\x{5965}|\x{5978}|\x{5986}|\x{5987}|\x{5988}|\x{59A9}|\x{59AA}|\x{59AB}|\x{59D7}|\x{59F9}|\x{5A04}|\x{5A05}|\x{5A06}|\x{5A07}|\x{5A08}|\x{5A31}|\x{5A32}|\x{5A34}|\x{5A73}|\x{5A74}|\x{5A75}|\x{5A76}|\x{5AAA}|\x{5AAD}|\x{5AD2}|\x{5AD4}|\x{5AF1}|\x{5B37}|\x{5B59}|\x{5B66}|\x{5B6A}|\x{5B81}|\x{5B9D}|\x{5B9E}|\x{5BA0}|\x{5BA1}|\x{5BAA}|\x{5BAB}|\x{5BBD}|\x{5BBE}|\x{5BDD}|\x{5BF9}|\x{5BFB}|\x{5BFC}|\x{5BFF}|\x{5C06}|\x{5C14}|\x{5C18}|\x{5C1D}|\x{5C27}|\x{5C34}|\x{5C38}|\x{5C3D}|\x{5C42}|\x{5C43}|\x{5C49}|\x{5C4A}|\x{5C5E}|\x{5C61}|\x{5C66}|\x{5C7F}|\x{5C81}|\x{5C82}|\x{5C96}|\x{5C97}|\x{5C98}|\x{5C99}|\x{5C9A}|\x{5C9B}|\x{5CAD}|\x{5CBD}|\x{5CBF}|\x{5CC4}|\x{5CE1}|\x{5CE3}|\x{5CE4}|\x{5CE5}|\x{5CE6}|\x{5D02}|\x{5D03}|\x{5D04}|\x{5D2D}|\x{5D58}|\x{5D5A}|\x{5D5D}|\x{5DC5}|\x{5DE9}|\x{5DEF}|\x{5E01}|\x{5E05}|\x{5E08}|\x{5E0F}|\x{5E10}|\x{5E18}|\x{5E1C}|\x{5E26}|\x{5E27}|\x{5E2E}|\x{5E31}|\x{5E3B}|\x{5E3C}|\x{5E42}|\x{5E72}|\x{5E76}|\x{5E7F}|\x{5E84}|\x{5E86}|\x{5E90}|\x{5E91}|\x{5E93}|\x{5E94}|\x{5E99}|\x{5E9E}|\x{5E9F}|\x{5EEA}|\x{5F00}|\x{5F02}|\x{5F03}|\x{5F11}|\x{5F20}|\x{5F25}|\x{5F2A}|\x{5F2F}|\x{5F39}|\x{5F3A}|\x{5F52}|\x{5F53}|\x{5F55}|\x{5F5D}|\x{5F5F}|\x{5F66}|\x{5F68}|\x{5F7B}|\x{5F81}|\x{5F84}|\x{5F95}|\x{5FA1}|\x{5FB5}|\x{5FC6}|\x{5FCF}|\x{5FD7}|\x{5FE7}|\x{5FFE}|\x{6000}|\x{6001}|\x{6002}|\x{6003}|\x{6004}|\x{6005}|\x{6006}|\x{601C}|\x{603B}|\x{603C}|\x{603F}|\x{604B}|\x{6052}|\x{6073}|\x{6076}|\x{6078}|\x{6079}|\x{607A}|\x{607B}|\x{607C}|\x{607D}|\x{60A6}|\x{60AB}|\x{60AC}|\x{60AD}|\x{60AE}|\x{60AF}|\x{60CA}|\x{60E7}|\x{60E8}|\x{60E9}|\x{60EB}|\x{60EC}|\x{60ED}|\x{60EE}|\x{60EF}|\x{6120}|\x{6124}|\x{6126}|\x{613F}|\x{6151}|\x{61D1}|\x{61D2}|\x{61D4}|\x{6206}|\x{620B}|\x{620F}|\x{6217}|\x{6218}|\x{622C}|\x{622F}|\x{6237}|\x{6251}|\x{6267}|\x{6269}|\x{626A}|\x{626B}|\x{626C}|\x{6270}|\x{629A}|\x{629B}|\x{629F}|\x{62A0}|\x{62A1}|\x{62A2}|\x{62A4}|\x{62A5}|\x{62C5}|\x{62DF}|\x{62E2}|\x{62E3}|\x{62E5}|\x{62E6}|\x{62E7}|\x{62E8}|\x{62E9}|\x{6302}|\x{631A}|\x{631B}|\x{631C}|\x{631D}|\x{631E}|\x{631F}|\x{6320}|\x{6321}|\x{6322}|\x{6323}|\x{6324}|\x{6325}|\x{6326}|\x{633D}|\x{635D}|\x{635E}|\x{635F}|\x{6361}|\x{6362}|\x{6363}|\x{636E}|\x{63B3}|\x{63B4}|\x{63B7}|\x{63B8}|\x{63BA}|\x{63BC}|\x{63FD}|\x{63FE}|\x{63FF}|\x{6400}|\x{6401}|\x{6402}|\x{6405}|\x{643A}|\x{6444}|\x{6445}|\x{6446}|\x{6447}|\x{6448}|\x{644A}|\x{6484}|\x{6491}|\x{64B5}|\x{64B7}|\x{64B8}|\x{64BA}|\x{64DE}|\x{6512}|\x{654C}|\x{655B}|\x{6569}|\x{6570}|\x{658B}|\x{6593}|\x{6597}|\x{65A9}|\x{65AD}|\x{65E0}|\x{65E7}|\x{65F6}|\x{65F7}|\x{65F8}|\x{6619}|\x{663C}|\x{663D}|\x{663E}|\x{664B}|\x{6652}|\x{6653}|\x{6654}|\x{6655}|\x{6656}|\x{6682}|\x{66A7}|\x{672F}|\x{6734}|\x{673A}|\x{6740}|\x{6742}|\x{6743}|\x{6746}|\x{6761}|\x{6765}|\x{6768}|\x{6769}|\x{6770}|\x{677E}|\x{677F}|\x{6781}|\x{6784}|\x{679E}|\x{67A2}|\x{67A3}|\x{67A5}|\x{67A7}|\x{67A8}|\x{67AA}|\x{67AB}|\x{67AD}|\x{67DC}|\x{67E0}|\x{67FD}|\x{6800}|\x{6805}|\x{6807}|\x{6808}|\x{6809}|\x{680A}|\x{680B}|\x{680C}|\x{680E}|\x{680F}|\x{6811}|\x{6816}|\x{6817}|\x{6837}|\x{683E}|\x{6860}|\x{6861}|\x{6862}|\x{6863}|\x{6864}|\x{6865}|\x{6866}|\x{6867}|\x{6868}|\x{6869}|\x{686A}|\x{68A6}|\x{68BC}|\x{68BE}|\x{68BF}|\x{68C0}|\x{68C1}|\x{68C2}|\x{6901}|\x{691D}|\x{691F}|\x{6920}|\x{6922}|\x{6924}|\x{692B}|\x{692D}|\x{697C}|\x{6984}|\x{6985}|\x{6987}|\x{6988}|\x{6989}|\x{69DA}|\x{69DB}|\x{69DF}|\x{69E0}|\x{6A2A}|\x{6A2F}|\x{6A31}|\x{6A65}|\x{6A71}|\x{6A79}|\x{6A7C}|\x{6AA9}|\x{6B22}|\x{6B24}|\x{6B27}|\x{6B7C}|\x{6B81}|\x{6B87}|\x{6B8B}|\x{6B92}|\x{6B93}|\x{6B9A}|\x{6BA1}|\x{6BB4}|\x{6BC1}|\x{6BC2}|\x{6BD5}|\x{6BD9}|\x{6BE1}|\x{6BF5}|\x{6C07}|\x{6C14}|\x{6C22}|\x{6C29}|\x{6C32}|\x{6C47}|\x{6C49}|\x{6C64}|\x{6C79}|\x{6C88}|\x{6C9F}|\x{6CA1}|\x{6CA3}|\x{6CA4}|\x{6CA5}|\x{6CA6}|\x{6CA7}|\x{6CA8}|\x{6CA9}|\x{6CAA}|\x{6CDE}|\x{6CE8}|\x{6CEA}|\x{6CF6}|\x{6CF7}|\x{6CF8}|\x{6CFA}|\x{6CFB}|\x{6CFC}|\x{6CFD}|\x{6CFE}|\x{6D01}|\x{6D12}|\x{6D3C}|\x{6D43}|\x{6D45}|\x{6D46}|\x{6D47}|\x{6D48}|\x{6D4A}|\x{6D4B}|\x{6D4D}|\x{6D4E}|\x{6D4F}|\x{6D50}|\x{6D51}|\x{6D52}|\x{6D53}|\x{6D54}|\x{6D55}|\x{6D82}|\x{6D9B}|\x{6D9D}|\x{6D9E}|\x{6D9F}|\x{6DA0}|\x{6DA1}|\x{6DA2}|\x{6DA3}|\x{6DA4}|\x{6DA6}|\x{6DA7}|\x{6DA8}|\x{6DA9}|\x{6DC0}|\x{6E0A}|\x{6E0C}|\x{6E0D}|\x{6E0E}|\x{6E10}|\x{6E11}|\x{6E14}|\x{6E17}|\x{6E29}|\x{6E7E}|\x{6E7F}|\x{6E83}|\x{6E85}|\x{6E86}|\x{6E87}|\x{6ED7}|\x{6EDA}|\x{6EDE}|\x{6EDF}|\x{6EE0}|\x{6EE1}|\x{6EE2}|\x{6EE4}|\x{6EE5}|\x{6EE6}|\x{6EE8}|\x{6EE9}|\x{6EEA}|\x{6F13}|\x{6F24}|\x{6F46}|\x{6F47}|\x{6F4B}|\x{6F4D}|\x{6F5C}|\x{6F74}|\x{6F9B}|\x{6F9C}|\x{6FD1}|\x{6FD2}|\x{704F}|\x{706D}|\x{706F}|\x{7075}|\x{707E}|\x{707F}|\x{7080}|\x{7089}|\x{709C}|\x{709D}|\x{70B9}|\x{70BC}|\x{70BD}|\x{70C1}|\x{70C2}|\x{70C3}|\x{70DB}|\x{70DF}|\x{70E6}|\x{70E7}|\x{70E8}|\x{70E9}|\x{70EB}|\x{70EC}|\x{70ED}|\x{7115}|\x{7116}|\x{7118}|\x{7174}|\x{7231}|\x{7237}|\x{724D}|\x{7266}|\x{7275}|\x{727A}|\x{728A}|\x{72B6}|\x{72B7}|\x{72B8}|\x{72B9}|\x{72C8}|\x{72DD}|\x{72DE}|\x{72EC}|\x{72ED}|\x{72EE}|\x{72EF}|\x{72F0}|\x{72F1}|\x{72F2}|\x{7303}|\x{730E}|\x{7315}|\x{7321}|\x{732A}|\x{732B}|\x{732C}|\x{732E}|\x{736D}|\x{7391}|\x{739A}|\x{739B}|\x{73AE}|\x{73AF}|\x{73B0}|\x{73B1}|\x{73BA}|\x{73D0}|\x{73D1}|\x{73F0}|\x{73F2}|\x{740F}|\x{7410}|\x{743C}|\x{7476}|\x{7477}|\x{748E}|\x{74D2}|\x{74EF}|\x{7535}|\x{753B}|\x{7545}|\x{7574}|\x{7596}|\x{7597}|\x{759F}|\x{75A0}|\x{75A1}|\x{75AC}|\x{75AD}|\x{75AE}|\x{75AF}|\x{75B1}|\x{75B4}|\x{75C7}|\x{75C8}|\x{75C9}|\x{75D2}|\x{75D6}|\x{75E8}|\x{75EA}|\x{75EB}|\x{7605}|\x{7606}|\x{7617}|\x{7618}|\x{762A}|\x{762B}|\x{763E}|\x{763F}|\x{765E}|\x{7663}|\x{766B}|\x{7691}|\x{76B1}|\x{76B2}|\x{76CF}|\x{76D0}|\x{76D1}|\x{76D6}|\x{76D7}|\x{76D8}|\x{770D}|\x{7726}|\x{772C}|\x{7740}|\x{7741}|\x{7750}|\x{7751}|\x{7786}|\x{7792}|\x{77A9}|\x{77EB}|\x{77F6}|\x{77FE}|\x{77FF}|\x{7800}|\x{7801}|\x{7816}|\x{7817}|\x{781A}|\x{781C}|\x{783A}|\x{783B}|\x{783E}|\x{7840}|\x{7841}|\x{7855}|\x{7856}|\x{7857}|\x{7859}|\x{785A}|\x{786E}|\x{7875}|\x{7877}|\x{788D}|\x{789B}|\x{789C}|\x{793C}|\x{7943}|\x{794E}|\x{7962}|\x{796F}|\x{7977}|\x{7978}|\x{7980}|\x{7984}|\x{7985}|\x{79BB}|\x{79C3}|\x{79C6}|\x{79CD}|\x{79EF}|\x{79F0}|\x{79FD}|\x{79FE}|\x{7A06}|\x{7A0E}|\x{7A23}|\x{7A33}|\x{7A51}|\x{7A77}|\x{7A83}|\x{7A8D}|\x{7A8E}|\x{7A91}|\x{7A9C}|\x{7A9D}|\x{7AA5}|\x{7AA6}|\x{7AAD}|\x{7AD6}|\x{7ADE}|\x{7B03}|\x{7B0B}|\x{7B14}|\x{7B15}|\x{7B3A}|\x{7B3C}|\x{7B3E}|\x{7B51}|\x{7B5A}|\x{7B5B}|\x{7B5C}|\x{7B5D}|\x{7B79}|\x{7B7C}|\x{7B7E}|\x{7B80}|\x{7B93}|\x{7BA6}|\x{7BA7}|\x{7BA8}|\x{7BA9}|\x{7BAA}|\x{7BAB}|\x{7BD1}|\x{7BD3}|\x{7BEE}|\x{7BEF}|\x{7BF1}|\x{7C16}|\x{7C41}|\x{7C74}|\x{7C7B}|\x{7C7C}|\x{7C9C}|\x{7C9D}|\x{7CA4}|\x{7CAA}|\x{7CAE}|\x{7CC1}|\x{7CC7}|\x{7CFB}|\x{7D27}|\x{7D2F}|\x{7D77}|\x{7E9F}|\x{7EA0}|\x{7EA1}|\x{7EA2}|\x{7EA3}|\x{7EA4}|\x{7EA5}|\x{7EA6}|\x{7EA7}|\x{7EA8}|\x{7EA9}|\x{7EAA}|\x{7EAB}|\x{7EAC}|\x{7EAD}|\x{7EAE}|\x{7EAF}|\x{7EB0}|\x{7EB1}|\x{7EB2}|\x{7EB3}|\x{7EB4}|\x{7EB5}|\x{7EB6}|\x{7EB7}|\x{7EB8}|\x{7EB9}|\x{7EBA}|\x{7EBB}|\x{7EBC}|\x{7EBD}|\x{7EBE}|\x{7EBF}|\x{7EC0}|\x{7EC1}|\x{7EC2}|\x{7EC3}|\x{7EC4}|\x{7EC5}|\x{7EC6}|\x{7EC7}|\x{7EC8}|\x{7EC9}|\x{7ECA}|\x{7ECB}|\x{7ECC}|\x{7ECD}|\x{7ECE}|\x{7ECF}|\x{7ED0}|\x{7ED1}|\x{7ED2}|\x{7ED3}|\x{7ED4}|\x{7ED5}|\x{7ED6}|\x{7ED7}|\x{7ED8}|\x{7ED9}|\x{7EDA}|\x{7EDB}|\x{7EDC}|\x{7EDD}|\x{7EDE}|\x{7EDF}|\x{7EE0}|\x{7EE1}|\x{7EE2}|\x{7EE3}|\x{7EE4}|\x{7EE5}|\x{7EE6}|\x{7EE7}|\x{7EE8}|\x{7EE9}|\x{7EEA}|\x{7EEB}|\x{7EEC}|\x{7EED}|\x{7EEE}|\x{7EEF}|\x{7EF0}|\x{7EF1}|\x{7EF2}|\x{7EF3}|\x{7EF4}|\x{7EF5}|\x{7EF6}|\x{7EF7}|\x{7EF8}|\x{7EF9}|\x{7EFA}|\x{7EFB}|\x{7EFC}|\x{7EFD}|\x{7EFE}|\x{7EFF}|\x{7F00}|\x{7F01}|\x{7F02}|\x{7F03}|\x{7F04}|\x{7F05}|\x{7F06}|\x{7F07}|\x{7F08}|\x{7F09}|\x{7F0A}|\x{7F0B}|\x{7F0C}|\x{7F0D}|\x{7F0E}|\x{7F0F}|\x{7F11}|\x{7F12}|\x{7F13}|\x{7F14}|\x{7F15}|\x{7F16}|\x{7F17}|\x{7F18}|\x{7F19}|\x{7F1A}|\x{7F1B}|\x{7F1C}|\x{7F1D}|\x{7F1E}|\x{7F1F}|\x{7F20}|\x{7F21}|\x{7F22}|\x{7F23}|\x{7F24}|\x{7F25}|\x{7F26}|\x{7F27}|\x{7F28}|\x{7F29}|\x{7F2A}|\x{7F2B}|\x{7F2C}|\x{7F2D}|\x{7F2E}|\x{7F2F}|\x{7F30}|\x{7F31}|\x{7F32}|\x{7F33}|\x{7F34}|\x{7F35}|\x{7F42}|\x{7F51}|\x{7F57}|\x{7F5A}|\x{7F62}|\x{7F74}|\x{7F81}|\x{7F9F}|\x{7FD8}|\x{7FD9}|\x{7FDA}|\x{8022}|\x{8027}|\x{8038}|\x{803B}|\x{8042}|\x{804B}|\x{804C}|\x{804D}|\x{8054}|\x{8069}|\x{806A}|\x{8083}|\x{80A0}|\x{80A4}|\x{80AE}|\x{80B4}|\x{80BE}|\x{80BF}|\x{80C0}|\x{80C1}|\x{80C6}|\x{80DC}|\x{80E1}|\x{80E7}|\x{80E8}|\x{80EA}|\x{80EB}|\x{80F6}|\x{8109}|\x{810D}|\x{810F}|\x{8110}|\x{8111}|\x{8113}|\x{8114}|\x{811A}|\x{8131}|\x{8136}|\x{8138}|\x{814A}|\x{8158}|\x{816D}|\x{817B}|\x{817C}|\x{817D}|\x{817E}|\x{8191}|\x{81DC}|\x{81F4}|\x{8206}|\x{820D}|\x{8223}|\x{8230}|\x{8231}|\x{823B}|\x{8270}|\x{8273}|\x{827A}|\x{8282}|\x{8288}|\x{8297}|\x{829C}|\x{82A6}|\x{82B8}|\x{82C1}|\x{82C7}|\x{82C8}|\x{82CB}|\x{82CC}|\x{82CD}|\x{82CE}|\x{82CF}|\x{82E7}|\x{82F9}|\x{8303}|\x{830E}|\x{830F}|\x{8311}|\x{8314}|\x{8315}|\x{8327}|\x{8346}|\x{8350}|\x{8359}|\x{835A}|\x{835B}|\x{835C}|\x{835D}|\x{835E}|\x{835F}|\x{8360}|\x{8361}|\x{8363}|\x{8364}|\x{8365}|\x{8366}|\x{8367}|\x{8368}|\x{8369}|\x{836A}|\x{836B}|\x{836C}|\x{836D}|\x{836E}|\x{836F}|\x{8385}|\x{83B1}|\x{83B2}|\x{83B3}|\x{83B4}|\x{83B6}|\x{83B7}|\x{83B8}|\x{83B9}|\x{83BA}|\x{83BC}|\x{841D}|\x{8424}|\x{8425}|\x{8426}|\x{8427}|\x{8428}|\x{8471}|\x{8487}|\x{8489}|\x{848B}|\x{848C}|\x{84DD}|\x{84DF}|\x{84E0}|\x{84E3}|\x{84E5}|\x{84E6}|\x{8502}|\x{8537}|\x{8539}|\x{853A}|\x{853C}|\x{8570}|\x{8572}|\x{8574}|\x{85AE}|\x{85D3}|\x{8616}|\x{864F}|\x{8651}|\x{865A}|\x{866B}|\x{866C}|\x{866E}|\x{867D}|\x{867E}|\x{867F}|\x{8680}|\x{8681}|\x{8682}|\x{8683}|\x{8695}|\x{86AC}|\x{86CA}|\x{86CE}|\x{86CF}|\x{86EE}|\x{86F0}|\x{86F1}|\x{86F2}|\x{86F3}|\x{86F4}|\x{8715}|\x{8717}|\x{8721}|\x{8747}|\x{8748}|\x{8749}|\x{877C}|\x{877E}|\x{8780}|\x{87A8}|\x{87CF}|\x{8845}|\x{8854}|\x{8865}|\x{8868}|\x{886C}|\x{886E}|\x{8884}|\x{8885}|\x{8886}|\x{889C}|\x{88AD}|\x{88AF}|\x{88C5}|\x{88C6}|\x{88C8}|\x{88E2}|\x{88E3}|\x{88E4}|\x{88E5}|\x{891B}|\x{8934}|\x{8955}|\x{89C1}|\x{89C2}|\x{89C3}|\x{89C4}|\x{89C5}|\x{89C6}|\x{89C7}|\x{89C8}|\x{89C9}|\x{89CA}|\x{89CB}|\x{89CC}|\x{89CD}|\x{89CE}|\x{89CF}|\x{89D0}|\x{89D1}|\x{89DE}|\x{89E6}|\x{89EF}|\x{8A1A}|\x{8A5F}|\x{8A89}|\x{8A8A}|\x{8BA0}|\x{8BA1}|\x{8BA2}|\x{8BA3}|\x{8BA4}|\x{8BA5}|\x{8BA6}|\x{8BA7}|\x{8BA8}|\x{8BA9}|\x{8BAA}|\x{8BAB}|\x{8BAC}|\x{8BAD}|\x{8BAE}|\x{8BAF}|\x{8BB0}|\x{8BB1}|\x{8BB2}|\x{8BB3}|\x{8BB4}|\x{8BB5}|\x{8BB6}|\x{8BB7}|\x{8BB8}|\x{8BB9}|\x{8BBA}|\x{8BBB}|\x{8BBC}|\x{8BBD}|\x{8BBE}|\x{8BBF}|\x{8BC0}|\x{8BC1}|\x{8BC2}|\x{8BC3}|\x{8BC4}|\x{8BC5}|\x{8BC6}|\x{8BC7}|\x{8BC8}|\x{8BC9}|\x{8BCA}|\x{8BCB}|\x{8BCC}|\x{8BCD}|\x{8BCE}|\x{8BCF}|\x{8BD0}|\x{8BD1}|\x{8BD2}|\x{8BD3}|\x{8BD4}|\x{8BD5}|\x{8BD6}|\x{8BD7}|\x{8BD8}|\x{8BD9}|\x{8BDA}|\x{8BDB}|\x{8BDC}|\x{8BDD}|\x{8BDE}|\x{8BDF}|\x{8BE0}|\x{8BE1}|\x{8BE2}|\x{8BE3}|\x{8BE4}|\x{8BE5}|\x{8BE6}|\x{8BE7}|\x{8BE8}|\x{8BE9}|\x{8BEA}|\x{8BEB}|\x{8BEC}|\x{8BED}|\x{8BEE}|\x{8BEF}|\x{8BF0}|\x{8BF1}|\x{8BF2}|\x{8BF3}|\x{8BF4}|\x{8BF5}|\x{8BF6}|\x{8BF7}|\x{8BF8}|\x{8BF9}|\x{8BFA}|\x{8BFB}|\x{8BFC}|\x{8BFD}|\x{8BFE}|\x{8BFF}|\x{8C00}|\x{8C01}|\x{8C02}|\x{8C03}|\x{8C04}|\x{8C05}|\x{8C06}|\x{8C07}|\x{8C08}|\x{8C0A}|\x{8C0B}|\x{8C0C}|\x{8C0D}|\x{8C0E}|\x{8C0F}|\x{8C10}|\x{8C11}|\x{8C12}|\x{8C13}|\x{8C14}|\x{8C15}|\x{8C16}|\x{8C17}|\x{8C18}|\x{8C19}|\x{8C1A}|\x{8C1B}|\x{8C1C}|\x{8C1D}|\x{8C1E}|\x{8C1F}|\x{8C20}|\x{8C21}|\x{8C22}|\x{8C23}|\x{8C24}|\x{8C25}|\x{8C26}|\x{8C27}|\x{8C28}|\x{8C29}|\x{8C2A}|\x{8C2B}|\x{8C2C}|\x{8C2D}|\x{8C2E}|\x{8C2F}|\x{8C30}|\x{8C31}|\x{8C32}|\x{8C33}|\x{8C34}|\x{8C35}|\x{8C36}|\x{8C37}|\x{8C6E}|\x{8D1D}|\x{8D1E}|\x{8D1F}|\x{8D20}|\x{8D21}|\x{8D22}|\x{8D23}|\x{8D24}|\x{8D25}|\x{8D26}|\x{8D27}|\x{8D28}|\x{8D29}|\x{8D2A}|\x{8D2B}|\x{8D2C}|\x{8D2D}|\x{8D2E}|\x{8D2F}|\x{8D30}|\x{8D31}|\x{8D32}|\x{8D33}|\x{8D34}|\x{8D35}|\x{8D36}|\x{8D37}|\x{8D38}|\x{8D39}|\x{8D3A}|\x{8D3B}|\x{8D3C}|\x{8D3D}|\x{8D3E}|\x{8D3F}|\x{8D40}|\x{8D41}|\x{8D42}|\x{8D43}|\x{8D44}|\x{8D45}|\x{8D46}|\x{8D47}|\x{8D48}|\x{8D49}|\x{8D4A}|\x{8D4B}|\x{8D4C}|\x{8D4D}|\x{8D4E}|\x{8D4F}|\x{8D50}|\x{8D51}|\x{8D52}|\x{8D53}|\x{8D54}|\x{8D55}|\x{8D56}|\x{8D57}|\x{8D58}|\x{8D59}|\x{8D5A}|\x{8D5B}|\x{8D5C}|\x{8D5D}|\x{8D5E}|\x{8D5F}|\x{8D60}|\x{8D61}|\x{8D62}|\x{8D63}|\x{8D6A}|\x{8D75}|\x{8D76}|\x{8D8B}|\x{8DB1}|\x{8DB8}|\x{8DC3}|\x{8DC4}|\x{8DDE}|\x{8DF5}|\x{8DF6}|\x{8DF7}|\x{8DF8}|\x{8DF9}|\x{8DFB}|\x{8E0A}|\x{8E0C}|\x{8E2A}|\x{8E2C}|\x{8E2F}|\x{8E51}|\x{8E52}|\x{8E70}|\x{8E7F}|\x{8E8F}|\x{8E9C}|\x{8EAF}|\x{8F66}|\x{8F67}|\x{8F68}|\x{8F69}|\x{8F6A}|\x{8F6B}|\x{8F6C}|\x{8F6D}|\x{8F6E}|\x{8F6F}|\x{8F70}|\x{8F71}|\x{8F72}|\x{8F73}|\x{8F74}|\x{8F75}|\x{8F76}|\x{8F77}|\x{8F78}|\x{8F79}|\x{8F7A}|\x{8F7B}|\x{8F7C}|\x{8F7D}|\x{8F7E}|\x{8F7F}|\x{8F80}|\x{8F81}|\x{8F82}|\x{8F83}|\x{8F84}|\x{8F85}|\x{8F86}|\x{8F87}|\x{8F88}|\x{8F89}|\x{8F8A}|\x{8F8B}|\x{8F8C}|\x{8F8D}|\x{8F8E}|\x{8F8F}|\x{8F90}|\x{8F91}|\x{8F92}|\x{8F93}|\x{8F94}|\x{8F95}|\x{8F96}|\x{8F97}|\x{8F98}|\x{8F99}|\x{8F9A}|\x{8F9E}|\x{8FA9}|\x{8FAB}|\x{8FB9}|\x{8FBD}|\x{8FBE}|\x{8FC1}|\x{8FC7}|\x{8FC8}|\x{8FD0}|\x{8FD8}|\x{8FD9}|\x{8FDB}|\x{8FDC}|\x{8FDD}|\x{8FDE}|\x{8FDF}|\x{8FE9}|\x{8FF3}|\x{8FF9}|\x{9002}|\x{9009}|\x{900A}|\x{9012}|\x{9026}|\x{903B}|\x{9057}|\x{9065}|\x{9093}|\x{909D}|\x{90AC}|\x{90AE}|\x{90B9}|\x{90BA}|\x{90BB}|\x{90C1}|\x{90CF}|\x{90D0}|\x{90D1}|\x{90D3}|\x{90E6}|\x{90E7}|\x{90F8}|\x{9142}|\x{915D}|\x{9166}|\x{9171}|\x{917D}|\x{917E}|\x{917F}|\x{91C7}|\x{91CA}|\x{91CC}|\x{9274}|\x{92AE}|\x{933E}|\x{9485}|\x{9486}|\x{9487}|\x{9488}|\x{9489}|\x{948A}|\x{948B}|\x{948C}|\x{948D}|\x{948E}|\x{948F}|\x{9490}|\x{9491}|\x{9492}|\x{9493}|\x{9494}|\x{9495}|\x{9496}|\x{9497}|\x{9498}|\x{9499}|\x{949A}|\x{949B}|\x{949C}|\x{949D}|\x{949E}|\x{949F}|\x{94A0}|\x{94A1}|\x{94A2}|\x{94A3}|\x{94A4}|\x{94A5}|\x{94A6}|\x{94A7}|\x{94A8}|\x{94A9}|\x{94AA}|\x{94AB}|\x{94AC}|\x{94AD}|\x{94AE}|\x{94AF}|\x{94B0}|\x{94B1}|\x{94B2}|\x{94B3}|\x{94B4}|\x{94B5}|\x{94B6}|\x{94B7}|\x{94B8}|\x{94B9}|\x{94BA}|\x{94BB}|\x{94BC}|\x{94BD}|\x{94BE}|\x{94BF}|\x{94C0}|\x{94C1}|\x{94C2}|\x{94C3}|\x{94C4}|\x{94C5}|\x{94C6}|\x{94C7}|\x{94C8}|\x{94C9}|\x{94CA}|\x{94CB}|\x{94CC}|\x{94CD}|\x{94CE}|\x{94CF}|\x{94D0}|\x{94D1}|\x{94D2}|\x{94D3}|\x{94D4}|\x{94D5}|\x{94D6}|\x{94D7}|\x{94D8}|\x{94D9}|\x{94DA}|\x{94DB}|\x{94DC}|\x{94DD}|\x{94DE}|\x{94DF}|\x{94E0}|\x{94E1}|\x{94E2}|\x{94E3}|\x{94E4}|\x{94E5}|\x{94E6}|\x{94E7}|\x{94E8}|\x{94E9}|\x{94EA}|\x{94EB}|\x{94EC}|\x{94ED}|\x{94EE}|\x{94EF}|\x{94F0}|\x{94F1}|\x{94F2}|\x{94F3}|\x{94F4}|\x{94F5}|\x{94F6}|\x{94F7}|\x{94F8}|\x{94F9}|\x{94FA}|\x{94FB}|\x{94FC}|\x{94FD}|\x{94FE}|\x{94FF}|\x{9500}|\x{9501}|\x{9502}|\x{9503}|\x{9504}|\x{9505}|\x{9506}|\x{9507}|\x{9508}|\x{9509}|\x{950A}|\x{950B}|\x{950C}|\x{950D}|\x{950E}|\x{950F}|\x{9510}|\x{9511}|\x{9512}|\x{9513}|\x{9514}|\x{9515}|\x{9516}|\x{9517}|\x{9518}|\x{9519}|\x{951A}|\x{951B}|\x{951C}|\x{951D}|\x{951E}|\x{951F}|\x{9520}|\x{9521}|\x{9522}|\x{9523}|\x{9524}|\x{9525}|\x{9526}|\x{9527}|\x{9528}|\x{9529}|\x{952A}|\x{952B}|\x{952C}|\x{952D}|\x{952E}|\x{952F}|\x{9530}|\x{9531}|\x{9532}|\x{9533}|\x{9534}|\x{9535}|\x{9536}|\x{9537}|\x{9538}|\x{9539}|\x{953A}|\x{953B}|\x{953C}|\x{953D}|\x{953E}|\x{953F}|\x{9540}|\x{9541}|\x{9542}|\x{9543}|\x{9544}|\x{9545}|\x{9546}|\x{9547}|\x{9548}|\x{9549}|\x{954A}|\x{954B}|\x{954C}|\x{954D}|\x{954E}|\x{954F}|\x{9550}|\x{9551}|\x{9552}|\x{9553}|\x{9554}|\x{9555}|\x{9556}|\x{9557}|\x{9558}|\x{9559}|\x{955A}|\x{955B}|\x{955C}|\x{955D}|\x{955E}|\x{955F}|\x{9560}|\x{9561}|\x{9562}|\x{9563}|\x{9564}|\x{9565}|\x{9566}|\x{9567}|\x{9568}|\x{9569}|\x{956A}|\x{956B}|\x{956C}|\x{956D}|\x{956E}|\x{956F}|\x{9570}|\x{9571}|\x{9572}|\x{9573}|\x{9574}|\x{9575}|\x{9576}|\x{957F}|\x{95E8}|\x{95E9}|\x{95EA}|\x{95EB}|\x{95EC}|\x{95ED}|\x{95EE}|\x{95EF}|\x{95F0}|\x{95F1}|\x{95F2}|\x{95F3}|\x{95F4}|\x{95F5}|\x{95F6}|\x{95F7}|\x{95F8}|\x{95F9}|\x{95FA}|\x{95FB}|\x{95FC}|\x{95FD}|\x{95FE}|\x{95FF}|\x{9600}|\x{9601}|\x{9602}|\x{9603}|\x{9604}|\x{9605}|\x{9606}|\x{9607}|\x{9608}|\x{9609}|\x{960A}|\x{960B}|\x{960C}|\x{960D}|\x{960E}|\x{960F}|\x{9610}|\x{9611}|\x{9612}|\x{9613}|\x{9614}|\x{9615}|\x{9616}|\x{9617}|\x{9618}|\x{9619}|\x{961A}|\x{961B}|\x{961F}|\x{9633}|\x{9634}|\x{9635}|\x{9636}|\x{9645}|\x{9646}|\x{9647}|\x{9648}|\x{9649}|\x{9655}|\x{9667}|\x{9668}|\x{9669}|\x{968F}|\x{9690}|\x{96B6}|\x{96BD}|\x{96BE}|\x{96CF}|\x{96E0}|\x{96F3}|\x{96FE}|\x{9701}|\x{9721}|\x{972D}|\x{9753}|\x{9759}|\x{9762}|\x{9765}|\x{9791}|\x{9792}|\x{97AF}|\x{97E6}|\x{97E7}|\x{97E8}|\x{97E9}|\x{97EA}|\x{97EB}|\x{97EC}|\x{97F5}|\x{9875}|\x{9876}|\x{9877}|\x{9878}|\x{9879}|\x{987A}|\x{987B}|\x{987C}|\x{987D}|\x{987E}|\x{987F}|\x{9880}|\x{9881}|\x{9882}|\x{9883}|\x{9884}|\x{9885}|\x{9886}|\x{9887}|\x{9888}|\x{9889}|\x{988A}|\x{988B}|\x{988C}|\x{988D}|\x{988E}|\x{988F}|\x{9890}|\x{9891}|\x{9892}|\x{9893}|\x{9894}|\x{9895}|\x{9896}|\x{9897}|\x{9898}|\x{9899}|\x{989A}|\x{989B}|\x{989C}|\x{989D}|\x{989E}|\x{989F}|\x{98A0}|\x{98A1}|\x{98A2}|\x{98A3}|\x{98A4}|\x{98A5}|\x{98A6}|\x{98A7}|\x{98CE}|\x{98CF}|\x{98D0}|\x{98D1}|\x{98D2}|\x{98D3}|\x{98D4}|\x{98D5}|\x{98D6}|\x{98D7}|\x{98D8}|\x{98D9}|\x{98DA}|\x{98DE}|\x{98E8}|\x{990D}|\x{9963}|\x{9964}|\x{9965}|\x{9966}|\x{9967}|\x{9968}|\x{9969}|\x{996A}|\x{996B}|\x{996C}|\x{996D}|\x{996E}|\x{996F}|\x{9970}|\x{9971}|\x{9972}|\x{9973}|\x{9974}|\x{9975}|\x{9976}|\x{9977}|\x{9978}|\x{9979}|\x{997A}|\x{997B}|\x{997C}|\x{997D}|\x{997E}|\x{997F}|\x{9980}|\x{9981}|\x{9982}|\x{9983}|\x{9984}|\x{9985}|\x{9986}|\x{9987}|\x{9988}|\x{9989}|\x{998A}|\x{998B}|\x{998C}|\x{998D}|\x{998E}|\x{998F}|\x{9990}|\x{9991}|\x{9992}|\x{9993}|\x{9994}|\x{9995}|\x{9A6C}|\x{9A6D}|\x{9A6E}|\x{9A6F}|\x{9A70}|\x{9A71}|\x{9A72}|\x{9A73}|\x{9A74}|\x{9A75}|\x{9A76}|\x{9A77}|\x{9A78}|\x{9A79}|\x{9A7A}|\x{9A7B}|\x{9A7C}|\x{9A7D}|\x{9A7E}|\x{9A7F}|\x{9A80}|\x{9A81}|\x{9A82}|\x{9A83}|\x{9A84}|\x{9A85}|\x{9A86}|\x{9A87}|\x{9A88}|\x{9A89}|\x{9A8A}|\x{9A8B}|\x{9A8C}|\x{9A8D}|\x{9A8E}|\x{9A8F}|\x{9A90}|\x{9A91}|\x{9A92}|\x{9A93}|\x{9A94}|\x{9A95}|\x{9A96}|\x{9A97}|\x{9A98}|\x{9A99}|\x{9A9A}|\x{9A9B}|\x{9A9C}|\x{9A9D}|\x{9A9E}|\x{9A9F}|\x{9AA0}|\x{9AA1}|\x{9AA2}|\x{9AA3}|\x{9AA4}|\x{9AA5}|\x{9AA6}|\x{9AA7}|\x{9AC5}|\x{9ACB}|\x{9ACC}|\x{9B13}|\x{9B36}|\x{9B47}|\x{9B49}|\x{9C7C}|\x{9C7D}|\x{9C7E}|\x{9C7F}|\x{9C80}|\x{9C81}|\x{9C82}|\x{9C83}|\x{9C84}|\x{9C85}|\x{9C86}|\x{9C88}|\x{9C89}|\x{9C8A}|\x{9C8B}|\x{9C8C}|\x{9C8D}|\x{9C8E}|\x{9C8F}|\x{9C90}|\x{9C91}|\x{9C92}|\x{9C93}|\x{9C94}|\x{9C95}|\x{9C96}|\x{9C97}|\x{9C98}|\x{9C99}|\x{9C9A}|\x{9C9B}|\x{9C9C}|\x{9C9D}|\x{9C9E}|\x{9C9F}|\x{9CA0}|\x{9CA1}|\x{9CA2}|\x{9CA3}|\x{9CA4}|\x{9CA5}|\x{9CA6}|\x{9CA7}|\x{9CA8}|\x{9CA9}|\x{9CAA}|\x{9CAB}|\x{9CAC}|\x{9CAD}|\x{9CAE}|\x{9CAF}|\x{9CB0}|\x{9CB1}|\x{9CB2}|\x{9CB3}|\x{9CB4}|\x{9CB5}|\x{9CB7}|\x{9CB8}|\x{9CB9}|\x{9CBA}|\x{9CBB}|\x{9CBC}|\x{9CBD}|\x{9CBE}|\x{9CBF}|\x{9CC0}|\x{9CC1}|\x{9CC2}|\x{9CC3}|\x{9CC4}|\x{9CC5}|\x{9CC6}|\x{9CC7}|\x{9CC8}|\x{9CC9}|\x{9CCA}|\x{9CCB}|\x{9CCC}|\x{9CCD}|\x{9CCE}|\x{9CCF}|\x{9CD0}|\x{9CD1}|\x{9CD2}|\x{9CD3}|\x{9CD4}|\x{9CD5}|\x{9CD6}|\x{9CD7}|\x{9CD8}|\x{9CD9}|\x{9CDA}|\x{9CDB}|\x{9CDC}|\x{9CDD}|\x{9CDE}|\x{9CDF}|\x{9CE0}|\x{9CE1}|\x{9CE2}|\x{9CE3}|\x{9E1F}|\x{9E20}|\x{9E21}|\x{9E22}|\x{9E23}|\x{9E24}|\x{9E25}|\x{9E26}|\x{9E27}|\x{9E28}|\x{9E29}|\x{9E2A}|\x{9E2B}|\x{9E2C}|\x{9E2D}|\x{9E2E}|\x{9E2F}|\x{9E30}|\x{9E31}|\x{9E32}|\x{9E33}|\x{9E34}|\x{9E35}|\x{9E36}|\x{9E37}|\x{9E38}|\x{9E39}|\x{9E3A}|\x{9E3B}|\x{9E3C}|\x{9E3D}|\x{9E3E}|\x{9E3F}|\x{9E40}|\x{9E41}|\x{9E42}|\x{9E43}|\x{9E44}|\x{9E45}|\x{9E46}|\x{9E47}|\x{9E48}|\x{9E49}|\x{9E4A}|\x{9E4B}|\x{9E4C}|\x{9E4D}|\x{9E4E}|\x{9E4F}|\x{9E50}|\x{9E51}|\x{9E52}|\x{9E53}|\x{9E54}|\x{9E55}|\x{9E56}|\x{9E57}|\x{9E58}|\x{9E59}|\x{9E5A}|\x{9E5B}|\x{9E5C}|\x{9E5D}|\x{9E5E}|\x{9E5F}|\x{9E60}|\x{9E61}|\x{9E62}|\x{9E63}|\x{9E64}|\x{9E65}|\x{9E66}|\x{9E67}|\x{9E68}|\x{9E69}|\x{9E6A}|\x{9E6B}|\x{9E6C}|\x{9E6D}|\x{9E6E}|\x{9E6F}|\x{9E70}|\x{9E71}|\x{9E72}|\x{9E73}|\x{9E74}|\x{9E7E}|\x{9EA6}|\x{9EB8}|\x{9EC4}|\x{9EC9}|\x{9EE1}|\x{9EE9}|\x{9EEA}|\x{9EFE}|\x{9F0B}|\x{9F0D}|\x{9F17}|\x{9F39}|\x{9F50}|\x{9F51}|\x{9F7F}|\x{9F80}|\x{9F81}|\x{9F82}|\x{9F83}|\x{9F84}|\x{9F85}|\x{9F86}|\x{9F87}|\x{9F88}|\x{9F89}|\x{9F8A}|\x{9F8B}|\x{9F8C}|\x{9F99}|\x{9F9A}|\x{9F9B}|\x{9F9F}|\x{9FCF}|\x{9FD3}|\x{9FD4}|\x{9FED}|\x{201B2}|\x{201BF}|\x{20242}|\x{20257}|\x{206B3}|\x{206C5}|\x{206C6}|\x{20BDF}|\x{20BE0}|\x{20CA5}|\x{20D22}|\x{20D78}|\x{20D7E}|\x{212C0}|\x{212D7}|\x{21484}|\x{21760}|\x{217B1}|\x{21B5C}|\x{21B6C}|\x{21DB4}|\x{222C8}|\x{2261D}|\x{2261E}|\x{22653}|\x{226EF}|\x{22ACA}|\x{22ADE}|\x{22AEC}|\x{22B26}|\x{22B4F}|\x{22F7E}|\x{23190}|\x{23368}|\x{2336F}|\x{23370}|\x{23391}|\x{23424}|\x{23476}|\x{235CB}|\x{23613}|\x{23634}|\x{23637}|\x{23B64}|\x{23DA9}|\x{23DAB}|\x{23E23}|\x{23EBC}|\x{23EBD}|\x{23F77}|\x{241A1}|\x{241C3}|\x{241C4}|\x{24236}|\x{24237}|\x{24280}|\x{242CF}|\x{247A4}|\x{2480B}|\x{24980}|\x{24CC4}|\x{24DA7}|\x{24F6F}|\x{24F80}|\x{25158}|\x{25174}|\x{251A7}|\x{251E2}|\x{2541F}|\x{2542F}|\x{25430}|\x{2543B}|\x{259C2}|\x{25B00}|\x{25B1E}|\x{25B20}|\x{25B49}|\x{25B8B}|\x{25B9C}|\x{25C54}|\x{25E65}|\x{25E85}|\x{25E87}|\x{26208}|\x{26209}|\x{2620B}|\x{2620C}|\x{2620E}|\x{2620F}|\x{26210}|\x{26211}|\x{26212}|\x{26213}|\x{26214}|\x{26215}|\x{26216}|\x{26217}|\x{26218}|\x{26219}|\x{2621A}|\x{2621B}|\x{2621C}|\x{2621D}|\x{2621E}|\x{2621F}|\x{26220}|\x{26221}|\x{266E8}|\x{2677C}|\x{267D7}|\x{26A29}|\x{26C34}|\x{2725E}|\x{274AD}|\x{27BAA}|\x{27CD5}|\x{27E51}|\x{27E53}|\x{27E55}|\x{27E56}|\x{27E57}|\x{27FC8}|\x{28031}|\x{28074}|\x{280BA}|\x{28104}|\x{2816B}|\x{2816C}|\x{28257}|\x{28405}|\x{28406}|\x{28407}|\x{28408}|\x{28409}|\x{2840A}|\x{28479}|\x{28930}|\x{28C3E}|\x{28C3F}|\x{28C40}|\x{28C41}|\x{28C42}|\x{28C43}|\x{28C44}|\x{28C45}|\x{28C46}|\x{28C47}|\x{28C48}|\x{28C49}|\x{28C4A}|\x{28C4B}|\x{28C4C}|\x{28C4D}|\x{28C4E}|\x{28C4F}|\x{28C50}|\x{28C51}|\x{28C52}|\x{28C53}|\x{28C54}|\x{28C55}|\x{28C56}|\x{28DFF}|\x{28E00}|\x{28E01}|\x{28E02}|\x{28E03}|\x{28E04}|\x{28E05}|\x{28E06}|\x{28E07}|\x{28E09}|\x{28E0A}|\x{28E0B}|\x{28E0C}|\x{28E0E}|\x{28E18}|\x{28E1F}|\x{293FC}|\x{293FD}|\x{293FE}|\x{293FF}|\x{29400}|\x{29595}|\x{29596}|\x{29597}|\x{29665}|\x{29666}|\x{29667}|\x{29668}|\x{29669}|\x{2966A}|\x{2966B}|\x{2966C}|\x{2966D}|\x{2966E}|\x{2966F}|\x{29670}|\x{297FF}|\x{29800}|\x{29801}|\x{29802}|\x{29803}|\x{29805}|\x{29806}|\x{29807}|\x{29808}|\x{29809}|\x{2980A}|\x{2980B}|\x{2980C}|\x{2980E}|\x{2980F}|\x{29820}|\x{299E6}|\x{299E8}|\x{299E9}|\x{299EA}|\x{299EB}|\x{299EC}|\x{299ED}|\x{299EE}|\x{299EF}|\x{299F0}|\x{299F1}|\x{299F2}|\x{299F3}|\x{299F4}|\x{299F5}|\x{299F6}|\x{299FA}|\x{299FC}|\x{299FF}|\x{29A00}|\x{29A01}|\x{29A03}|\x{29A04}|\x{29A05}|\x{29A06}|\x{29A07}|\x{29A08}|\x{29A09}|\x{29A0A}|\x{29A0B}|\x{29A0C}|\x{29A0D}|\x{29A0E}|\x{29A0F}|\x{29A10}|\x{29B23}|\x{29B24}|\x{29BD2}|\x{29C92}|\x{29F79}|\x{29F7A}|\x{29F7B}|\x{29F7C}|\x{29F7D}|\x{29F7E}|\x{29F7F}|\x{29F81}|\x{29F82}|\x{29F83}|\x{29F84}|\x{29F85}|\x{29F86}|\x{29F87}|\x{29F88}|\x{29F8A}|\x{29F8B}|\x{29F8C}|\x{2A242}|\x{2A243}|\x{2A244}|\x{2A245}|\x{2A246}|\x{2A248}|\x{2A249}|\x{2A24A}|\x{2A24B}|\x{2A24C}|\x{2A24D}|\x{2A24E}|\x{2A24F}|\x{2A250}|\x{2A251}|\x{2A252}|\x{2A254}|\x{2A255}|\x{2A388}|\x{2A389}|\x{2A38A}|\x{2A38B}|\x{2A38D}|\x{2A52D}|\x{2A68F}|\x{2A690}|\x{2A79D}|\x{2A84F}|\x{2A8AE}|\x{2AA0A}|\x{2AA17}|\x{2AED0}|\x{2AFA2}|\x{2B061}|\x{2B088}|\x{2B128}|\x{2B138}|\x{2B300}|\x{2B328}|\x{2B359}|\x{2B35F}|\x{2B362}|\x{2B370}|\x{2B372}|\x{2B3CB}|\x{2B404}|\x{2B406}|\x{2B409}|\x{2B410}|\x{2B413}|\x{2B4E7}|\x{2B4E9}|\x{2B50E}|\x{2B5B8}|\x{2B5E0}|\x{2B5E6}|\x{2B5E7}|\x{2B5EE}|\x{2B5F4}|\x{2B61D}|\x{2B623}|\x{2B624}|\x{2B628}|\x{2B688}|\x{2B689}|\x{2B692}|\x{2B694}|\x{2B695}|\x{2B699}|\x{2B6AD}|\x{2B6DB}|\x{2B6DE}|\x{2B6E2}|\x{2B6F6}|\x{2B6F8}|\x{2C4FC}|\x{2C62D}|\x{2C925}|\x{2CBCE}|\x{2CE23})/u',$input) ){
		return true;
	}
	else {
		return false;
	}
}

function hasHantaiji(string $input)
{
	if ( preg_match('/(\x{346F}|\x{3473}|\x{3493}|\x{34E8}|\x{35F2}|\x{361A}|\x{3704}|\x{370F}|\x{3722}|\x{3737}|\x{379E}|\x{380F}|\x{389D}|\x{396E}|\x{398E}|\x{3A5C}|\x{3A73}|\x{3DFF}|\x{3E8F}|\x{3FE7}|\x{4039}|\x{406A}|\x{407B}|\x{4259}|\x{426C}|\x{4272}|\x{42AD}|\x{42B7}|\x{42D9}|\x{42DA}|\x{42FB}|\x{42FF}|\x{4308}|\x{430B}|\x{4316}|\x{431D}|\x{431F}|\x{4325}|\x{4330}|\x{4573}|\x{45FF}|\x{4661}|\x{4700}|\x{477B}|\x{477C}|\x{4788}|\x{48A8}|\x{4947}|\x{4951}|\x{4969}|\x{4971}|\x{4998}|\x{499B}|\x{499F}|\x{49B3}|\x{49E2}|\x{4A8F}|\x{4A97}|\x{4A98}|\x{4AF4}|\x{4B18}|\x{4B1D}|\x{4B1E}|\x{4B40}|\x{4B43}|\x{4B7F}|\x{4B9D}|\x{4B9E}|\x{4BA0}|\x{4BAB}|\x{4BB3}|\x{4BBE}|\x{4BC0}|\x{4C3E}|\x{4C59}|\x{4C6C}|\x{4C70}|\x{4C77}|\x{4C7D}|\x{4C81}|\x{4C96}|\x{4CB0}|\x{4D09}|\x{4D2C}|\x{4D34}|\x{4E1F}|\x{4E26}|\x{4E7E}|\x{4E82}|\x{4E9E}|\x{4F47}|\x{4F59}|\x{4F75}|\x{4F86}|\x{4F96}|\x{4FB6}|\x{4FC1}|\x{4FC2}|\x{4FD4}|\x{4FE0}|\x{4FE5}|\x{5000}|\x{5006}|\x{5008}|\x{5009}|\x{500B}|\x{5011}|\x{502B}|\x{5032}|\x{5049}|\x{5051}|\x{5074}|\x{5075}|\x{507D}|\x{5091}|\x{5096}|\x{5098}|\x{5099}|\x{50AD}|\x{50AF}|\x{50B3}|\x{50B4}|\x{50B5}|\x{50B7}|\x{50BE}|\x{50C2}|\x{50C5}|\x{50C9}|\x{50D1}|\x{50D5}|\x{50DE}|\x{50E5}|\x{50E8}|\x{50F9}|\x{5100}|\x{5102}|\x{5104}|\x{5108}|\x{5109}|\x{5110}|\x{5114}|\x{5115}|\x{5118}|\x{511F}|\x{5123}|\x{512A}|\x{5132}|\x{5137}|\x{5138}|\x{513A}|\x{513B}|\x{513C}|\x{514C}|\x{5152}|\x{5157}|\x{5167}|\x{5169}|\x{518A}|\x{51AA}|\x{51C8}|\x{51CD}|\x{51D9}|\x{51DC}|\x{51F1}|\x{5225}|\x{522A}|\x{5244}|\x{5247}|\x{524B}|\x{524E}|\x{5257}|\x{525B}|\x{525D}|\x{526E}|\x{5274}|\x{5275}|\x{527E}|\x{5283}|\x{5287}|\x{5289}|\x{528A}|\x{528C}|\x{528D}|\x{528F}|\x{5291}|\x{529A}|\x{52C1}|\x{52D5}|\x{52D9}|\x{52DB}|\x{52DD}|\x{52DE}|\x{52E2}|\x{52E9}|\x{52F1}|\x{52F5}|\x{52F8}|\x{52FB}|\x{532D}|\x{532F}|\x{5331}|\x{5340}|\x{5354}|\x{537B}|\x{5399}|\x{53AD}|\x{53B2}|\x{53B4}|\x{53C3}|\x{53C4}|\x{53E2}|\x{53F0}|\x{540C}|\x{540E}|\x{5412}|\x{5433}|\x{5436}|\x{5442}|\x{54BC}|\x{54E1}|\x{54EF}|\x{5504}|\x{551A}|\x{554F}|\x{555E}|\x{555F}|\x{5562}|\x{558E}|\x{559A}|\x{55AA}|\x{55AC}|\x{55AE}|\x{55B2}|\x{55C6}|\x{55C7}|\x{55CA}|\x{55CE}|\x{55DA}|\x{55E9}|\x{55F6}|\x{55F9}|\x{5606}|\x{560D}|\x{5613}|\x{5614}|\x{5616}|\x{5617}|\x{561C}|\x{5629}|\x{562E}|\x{562F}|\x{5630}|\x{5635}|\x{5638}|\x{563D}|\x{5645}|\x{5653}|\x{565A}|\x{565D}|\x{5660}|\x{5665}|\x{5666}|\x{566F}|\x{5672}|\x{5674}|\x{5678}|\x{5679}|\x{5680}|\x{5687}|\x{568C}|\x{5695}|\x{5699}|\x{56A6}|\x{56A8}|\x{56B2}|\x{56B3}|\x{56B4}|\x{56B6}|\x{56C0}|\x{56C1}|\x{56C2}|\x{56C5}|\x{56C8}|\x{56C9}|\x{56D1}|\x{56EA}|\x{5707}|\x{570B}|\x{570D}|\x{5712}|\x{5713}|\x{5716}|\x{5718}|\x{571E}|\x{57B5}|\x{57E1}|\x{57F0}|\x{57F7}|\x{5805}|\x{580A}|\x{5816}|\x{581D}|\x{582F}|\x{5831}|\x{5834}|\x{584A}|\x{584B}|\x{584F}|\x{5852}|\x{5857}|\x{5862}|\x{5864}|\x{5875}|\x{5879}|\x{588A}|\x{589C}|\x{58AE}|\x{58B3}|\x{58BE}|\x{58C7}|\x{58C8}|\x{58CB}|\x{58D3}|\x{58D8}|\x{58D9}|\x{58DA}|\x{58DE}|\x{58DF}|\x{58E0}|\x{58E2}|\x{58E9}|\x{58EF}|\x{58FA}|\x{58FC}|\x{58FD}|\x{5920}|\x{5922}|\x{593E}|\x{5950}|\x{5967}|\x{5969}|\x{596A}|\x{596E}|\x{597C}|\x{599D}|\x{59CD}|\x{59E6}|\x{5A1B}|\x{5A41}|\x{5A66}|\x{5A6D}|\x{5AA7}|\x{5AAF}|\x{5AB0}|\x{5ABC}|\x{5ABD}|\x{5AD7}|\x{5AF5}|\x{5AFB}|\x{5AFF}|\x{5B03}|\x{5B08}|\x{5B0B}|\x{5B0C}|\x{5B19}|\x{5B21}|\x{5B24}|\x{5B2A}|\x{5B30}|\x{5B38}|\x{5B4B}|\x{5B4C}|\x{5B6B}|\x{5B78}|\x{5B7F}|\x{5BAE}|\x{5BE2}|\x{5BE6}|\x{5BE7}|\x{5BE9}|\x{5BEB}|\x{5BEC}|\x{5BF5}|\x{5BF6}|\x{5C07}|\x{5C08}|\x{5C0B}|\x{5C0D}|\x{5C0E}|\x{5C37}|\x{5C46}|\x{5C4D}|\x{5C53}|\x{5C5C}|\x{5C62}|\x{5C64}|\x{5C68}|\x{5C69}|\x{5C6C}|\x{5CA1}|\x{5CF4}|\x{5CF6}|\x{5CFD}|\x{5D0D}|\x{5D17}|\x{5D22}|\x{5D2C}|\x{5D50}|\x{5D7C}|\x{5D81}|\x{5D84}|\x{5D87}|\x{5D94}|\x{5D97}|\x{5DA0}|\x{5DA2}|\x{5DA7}|\x{5DAE}|\x{5DB4}|\x{5DB8}|\x{5DBA}|\x{5DBC}|\x{5DCB}|\x{5DD2}|\x{5DD4}|\x{5DF0}|\x{5E25}|\x{5E2B}|\x{5E33}|\x{5E36}|\x{5E40}|\x{5E43}|\x{5E57}|\x{5E58}|\x{5E5F}|\x{5E63}|\x{5E6B}|\x{5E6C}|\x{5E79}|\x{5E7A}|\x{5E7E}|\x{5EAB}|\x{5EC1}|\x{5EC2}|\x{5EC4}|\x{5EC8}|\x{5EDA}|\x{5EDD}|\x{5EDF}|\x{5EE0}|\x{5EE1}|\x{5EE2}|\x{5EE3}|\x{5EE9}|\x{5EEC}|\x{5EF3}|\x{5F12}|\x{5F33}|\x{5F35}|\x{5F37}|\x{5F48}|\x{5F4C}|\x{5F4E}|\x{5F59}|\x{5F5E}|\x{5F60}|\x{5F65}|\x{5F72}|\x{5F81}|\x{5F8C}|\x{5F91}|\x{5F9E}|\x{5FA0}|\x{5FA9}|\x{5FB5}|\x{5FB9}|\x{5FD7}|\x{6046}|\x{6065}|\x{6085}|\x{609E}|\x{60B5}|\x{60B6}|\x{60E1}|\x{60F1}|\x{60F2}|\x{60FB}|\x{611B}|\x{611C}|\x{6128}|\x{6134}|\x{6137}|\x{613E}|\x{613F}|\x{6144}|\x{614B}|\x{614D}|\x{6158}|\x{615A}|\x{615F}|\x{6163}|\x{616A}|\x{616B}|\x{616E}|\x{6173}|\x{6176}|\x{6182}|\x{618A}|\x{6190}|\x{6191}|\x{6192}|\x{619A}|\x{61A4}|\x{61AB}|\x{61AE}|\x{61B2}|\x{61B6}|\x{61C0}|\x{61C7}|\x{61C9}|\x{61CC}|\x{61CD}|\x{61DF}|\x{61E3}|\x{61E8}|\x{61F2}|\x{61F6}|\x{61F7}|\x{61F8}|\x{61FA}|\x{61FC}|\x{61FE}|\x{6200}|\x{6207}|\x{6214}|\x{6227}|\x{6229}|\x{6230}|\x{6231}|\x{6232}|\x{6236}|\x{62CB}|\x{6329}|\x{633E}|\x{6368}|\x{636B}|\x{6383}|\x{6384}|\x{6386}|\x{6397}|\x{6399}|\x{639B}|\x{63A1}|\x{63C0}|\x{63DA}|\x{63DB}|\x{63EE}|\x{640D}|\x{6416}|\x{6417}|\x{6435}|\x{6436}|\x{644B}|\x{6451}|\x{645C}|\x{645F}|\x{646F}|\x{6473}|\x{6476}|\x{647B}|\x{6488}|\x{648F}|\x{6490}|\x{6493}|\x{649D}|\x{649F}|\x{64A3}|\x{64A5}|\x{64AB}|\x{64B2}|\x{64B3}|\x{64BB}|\x{64BE}|\x{64BF}|\x{64C1}|\x{64C4}|\x{64C7}|\x{64CA}|\x{64CB}|\x{64D3}|\x{64D4}|\x{64DA}|\x{64E0}|\x{64E3}|\x{64EC}|\x{64EF}|\x{64F0}|\x{64F1}|\x{64F2}|\x{64F4}|\x{64F7}|\x{64FA}|\x{64FB}|\x{64FC}|\x{64FD}|\x{64FE}|\x{6504}|\x{6506}|\x{650F}|\x{6514}|\x{6516}|\x{6519}|\x{651B}|\x{651C}|\x{651D}|\x{6522}|\x{6523}|\x{6524}|\x{652A}|\x{652C}|\x{6557}|\x{6558}|\x{6575}|\x{6578}|\x{6582}|\x{6583}|\x{6585}|\x{6586}|\x{6595}|\x{65AC}|\x{65B7}|\x{65BC}|\x{6642}|\x{6649}|\x{665D}|\x{6688}|\x{6689}|\x{6698}|\x{66A2}|\x{66AB}|\x{66C4}|\x{66C6}|\x{66C7}|\x{66C9}|\x{66CF}|\x{66D6}|\x{66E0}|\x{66E5}|\x{66E8}|\x{66EC}|\x{66F8}|\x{6703}|\x{6725}|\x{6727}|\x{6771}|\x{6774}|\x{6781}|\x{67F5}|\x{687F}|\x{6894}|\x{6898}|\x{689D}|\x{689F}|\x{68B2}|\x{68C4}|\x{68D6}|\x{68D7}|\x{68DF}|\x{68E1}|\x{68E7}|\x{68F2}|\x{68F6}|\x{690F}|\x{6932}|\x{694A}|\x{6953}|\x{6968}|\x{696D}|\x{6975}|\x{69AA}|\x{69AE}|\x{69B2}|\x{69BF}|\x{69CB}|\x{69CD}|\x{69E4}|\x{69E7}|\x{69E8}|\x{69F3}|\x{69F6}|\x{69FC}|\x{6A01}|\x{6A02}|\x{6A05}|\x{6A13}|\x{6A19}|\x{6A1E}|\x{6A22}|\x{6A23}|\x{6A2B}|\x{6A33}|\x{6A38}|\x{6A39}|\x{6A3A}|\x{6A3F}|\x{6A48}|\x{6A4B}|\x{6A5F}|\x{6A62}|\x{6A6B}|\x{6A81}|\x{6A89}|\x{6A94}|\x{6A9C}|\x{6A9F}|\x{6AA2}|\x{6AA3}|\x{6AAD}|\x{6AAE}|\x{6AAF}|\x{6AB3}|\x{6AB8}|\x{6ABB}|\x{6AC3}|\x{6AD3}|\x{6ADA}|\x{6ADB}|\x{6ADD}|\x{6ADE}|\x{6ADF}|\x{6AE5}|\x{6AE7}|\x{6AE8}|\x{6AEA}|\x{6AEB}|\x{6AEC}|\x{6AF1}|\x{6AF3}|\x{6AF8}|\x{6AFB}|\x{6B04}|\x{6B0A}|\x{6B0D}|\x{6B0F}|\x{6B12}|\x{6B13}|\x{6B16}|\x{6B1E}|\x{6B3D}|\x{6B50}|\x{6B5F}|\x{6B61}|\x{6B72}|\x{6B77}|\x{6B78}|\x{6B7F}|\x{6B98}|\x{6B9E}|\x{6BA4}|\x{6BA8}|\x{6BAB}|\x{6BAE}|\x{6BAF}|\x{6BB0}|\x{6BB2}|\x{6BBA}|\x{6BBC}|\x{6BC0}|\x{6BC6}|\x{6BFF}|\x{6C02}|\x{6C08}|\x{6C0C}|\x{6C23}|\x{6C2B}|\x{6C2C}|\x{6C33}|\x{6C7A}|\x{6C92}|\x{6C96}|\x{6CC1}|\x{6D36}|\x{6D79}|\x{6D87}|\x{6DBC}|\x{6DDA}|\x{6DE5}|\x{6DEA}|\x{6DF5}|\x{6DF6}|\x{6DFA}|\x{6E19}|\x{6E1B}|\x{6E22}|\x{6E26}|\x{6E2C}|\x{6E3E}|\x{6E4A}|\x{6E5E}|\x{6E6F}|\x{6E88}|\x{6E96}|\x{6E9D}|\x{6EAB}|\x{6EB3}|\x{6EC4}|\x{6EC5}|\x{6ECC}|\x{6ECE}|\x{6EEC}|\x{6EEF}|\x{6EF2}|\x{6EF8}|\x{6EFB}|\x{6EFE}|\x{6EFF}|\x{6F01}|\x{6F0A}|\x{6F1A}|\x{6F22}|\x{6F23}|\x{6F2C}|\x{6F32}|\x{6F35}|\x{6F38}|\x{6F3F}|\x{6F41}|\x{6F51}|\x{6F54}|\x{6F5B}|\x{6F64}|\x{6F6F}|\x{6F70}|\x{6F77}|\x{6F7F}|\x{6F80}|\x{6F85}|\x{6F86}|\x{6F87}|\x{6F97}|\x{6FA0}|\x{6FA4}|\x{6FA6}|\x{6FA9}|\x{6FAE}|\x{6FB1}|\x{6FBE}|\x{6FC1}|\x{6FC3}|\x{6FC4}|\x{6FC6}|\x{6FD5}|\x{6FD8}|\x{6FDC}|\x{6FDF}|\x{6FE4}|\x{6FE7}|\x{6FEB}|\x{6FF0}|\x{6FF1}|\x{6FFA}|\x{6FFC}|\x{6FFE}|\x{7002}|\x{7003}|\x{7005}|\x{7006}|\x{7007}|\x{7009}|\x{700B}|\x{700F}|\x{7015}|\x{7018}|\x{701D}|\x{701F}|\x{7020}|\x{7026}|\x{7027}|\x{7028}|\x{7030}|\x{7032}|\x{703E}|\x{7043}|\x{7044}|\x{7051}|\x{7055}|\x{7058}|\x{7059}|\x{705D}|\x{7060}|\x{7061}|\x{7063}|\x{7064}|\x{7067}|\x{707D}|\x{70BA}|\x{70CF}|\x{70F4}|\x{7121}|\x{7149}|\x{7152}|\x{7159}|\x{7162}|\x{7165}|\x{7169}|\x{716C}|\x{7171}|\x{7185}|\x{7189}|\x{718C}|\x{7192}|\x{7193}|\x{7197}|\x{71A1}|\x{71B1}|\x{71B2}|\x{71BE}|\x{71C1}|\x{71C8}|\x{71D2}|\x{71D9}|\x{71DC}|\x{71DF}|\x{71E6}|\x{71ED}|\x{71F4}|\x{71F6}|\x{71FC}|\x{71FE}|\x{7204}|\x{720D}|\x{7210}|\x{721B}|\x{722D}|\x{723A}|\x{723E}|\x{7246}|\x{7258}|\x{727D}|\x{7296}|\x{72A2}|\x{72A7}|\x{72C0}|\x{72F9}|\x{72FD}|\x{7319}|\x{7336}|\x{733B}|\x{7341}|\x{7344}|\x{7345}|\x{734E}|\x{7368}|\x{736A}|\x{736B}|\x{736E}|\x{7370}|\x{7371}|\x{7372}|\x{7375}|\x{7377}|\x{7378}|\x{737A}|\x{737B}|\x{737C}|\x{7380}|\x{7381}|\x{73FE}|\x{743A}|\x{743F}|\x{744B}|\x{7452}|\x{7463}|\x{7464}|\x{7469}|\x{746A}|\x{7472}|\x{747D}|\x{7489}|\x{74A3}|\x{74A6}|\x{74AB}|\x{74AF}|\x{74B0}|\x{74BD}|\x{74CA}|\x{74CF}|\x{74D4}|\x{74D5}|\x{74DA}|\x{750C}|\x{7522}|\x{755D}|\x{7562}|\x{756B}|\x{7570}|\x{7576}|\x{7587}|\x{758A}|\x{75D9}|\x{75FE}|\x{7602}|\x{760B}|\x{760D}|\x{7613}|\x{761E}|\x{7621}|\x{7627}|\x{762E}|\x{7632}|\x{763A}|\x{7642}|\x{7646}|\x{7647}|\x{7649}|\x{7658}|\x{765F}|\x{7662}|\x{7664}|\x{7665}|\x{7667}|\x{7669}|\x{766C}|\x{766D}|\x{766E}|\x{7670}|\x{7671}|\x{7672}|\x{767C}|\x{769A}|\x{769F}|\x{76B0}|\x{76B8}|\x{76BA}|\x{76DC}|\x{76DE}|\x{76E1}|\x{76E3}|\x{76E4}|\x{76E7}|\x{76EA}|\x{7725}|\x{773E}|\x{774D}|\x{774F}|\x{775C}|\x{775E}|\x{7798}|\x{779C}|\x{779E}|\x{77A4}|\x{77B6}|\x{77BC}|\x{77D3}|\x{77DA}|\x{77EF}|\x{785C}|\x{7864}|\x{7868}|\x{786F}|\x{7899}|\x{78A9}|\x{78AD}|\x{78B8}|\x{78BA}|\x{78BC}|\x{78BD}|\x{78D1}|\x{78DA}|\x{78E0}|\x{78E3}|\x{78E7}|\x{78EF}|\x{78FD}|\x{7904}|\x{7906}|\x{790E}|\x{7912}|\x{7919}|\x{7926}|\x{792A}|\x{792B}|\x{792C}|\x{7931}|\x{797F}|\x{798D}|\x{798E}|\x{7995}|\x{79A1}|\x{79A6}|\x{79AA}|\x{79AE}|\x{79B0}|\x{79B1}|\x{79BF}|\x{79C8}|\x{7A05}|\x{7A08}|\x{7A0F}|\x{7A1F}|\x{7A2E}|\x{7A31}|\x{7A40}|\x{7A4C}|\x{7A4D}|\x{7A4E}|\x{7A60}|\x{7A61}|\x{7A62}|\x{7A68}|\x{7A69}|\x{7A6B}|\x{7A6D}|\x{7AA9}|\x{7AAA}|\x{7AAE}|\x{7AAF}|\x{7AB5}|\x{7AB6}|\x{7ABA}|\x{7AC4}|\x{7AC5}|\x{7AC7}|\x{7ACA}|\x{7AF6}|\x{7B46}|\x{7B4D}|\x{7B67}|\x{7B74}|\x{7B8B}|\x{7B8F}|\x{7BC0}|\x{7BC4}|\x{7BC9}|\x{7BCB}|\x{7BD4}|\x{7BD8}|\x{7BE4}|\x{7BE9}|\x{7BF3}|\x{7C00}|\x{7C0D}|\x{7C1E}|\x{7C21}|\x{7C23}|\x{7C2B}|\x{7C39}|\x{7C3D}|\x{7C3E}|\x{7C43}|\x{7C4B}|\x{7C4C}|\x{7C54}|\x{7C59}|\x{7C5B}|\x{7C5C}|\x{7C5F}|\x{7C60}|\x{7C69}|\x{7C6A}|\x{7C6C}|\x{7C6E}|\x{7CB5}|\x{7CDD}|\x{7CDE}|\x{7CE7}|\x{7CF2}|\x{7CF4}|\x{7CF6}|\x{7CF9}|\x{7CFE}|\x{7D00}|\x{7D02}|\x{7D04}|\x{7D05}|\x{7D06}|\x{7D07}|\x{7D08}|\x{7D09}|\x{7D0B}|\x{7D0D}|\x{7D10}|\x{7D13}|\x{7D14}|\x{7D15}|\x{7D16}|\x{7D17}|\x{7D18}|\x{7D19}|\x{7D1A}|\x{7D1B}|\x{7D1C}|\x{7D1D}|\x{7D21}|\x{7D2C}|\x{7D30}|\x{7D31}|\x{7D32}|\x{7D33}|\x{7D35}|\x{7D39}|\x{7D3A}|\x{7D3C}|\x{7D3F}|\x{7D40}|\x{7D42}|\x{7D44}|\x{7D45}|\x{7D46}|\x{7D4E}|\x{7D50}|\x{7D55}|\x{7D5B}|\x{7D5D}|\x{7D5E}|\x{7D61}|\x{7D62}|\x{7D66}|\x{7D68}|\x{7D70}|\x{7D71}|\x{7D72}|\x{7D73}|\x{7D79}|\x{7D7A}|\x{7D80}|\x{7D81}|\x{7D83}|\x{7D86}|\x{7D87}|\x{7D88}|\x{7D8C}|\x{7D8F}|\x{7D90}|\x{7D93}|\x{7D9C}|\x{7D9D}|\x{7D9E}|\x{7DA0}|\x{7DA2}|\x{7DA3}|\x{7DAC}|\x{7DAD}|\x{7DAF}|\x{7DB0}|\x{7DB1}|\x{7DB2}|\x{7DB4}|\x{7DB5}|\x{7DB8}|\x{7DB9}|\x{7DBA}|\x{7DBB}|\x{7DBD}|\x{7DBE}|\x{7DBF}|\x{7DC4}|\x{7DC7}|\x{7DCA}|\x{7DCB}|\x{7DCD}|\x{7DD2}|\x{7DD3}|\x{7DD7}|\x{7DD8}|\x{7DD9}|\x{7DDA}|\x{7DDD}|\x{7DDE}|\x{7DE0}|\x{7DE1}|\x{7DE3}|\x{7DE6}|\x{7DE8}|\x{7DE9}|\x{7DEC}|\x{7DEF}|\x{7DF0}|\x{7DF1}|\x{7DF2}|\x{7DF4}|\x{7DF6}|\x{7DF7}|\x{7DF8}|\x{7DF9}|\x{7DFB}|\x{7E08}|\x{7E09}|\x{7E0A}|\x{7E0B}|\x{7E0E}|\x{7E10}|\x{7E11}|\x{7E15}|\x{7E17}|\x{7E1B}|\x{7E1D}|\x{7E1E}|\x{7E1F}|\x{7E23}|\x{7E2B}|\x{7E2C}|\x{7E2D}|\x{7E2E}|\x{7E31}|\x{7E32}|\x{7E33}|\x{7E35}|\x{7E36}|\x{7E37}|\x{7E39}|\x{7E3A}|\x{7E3D}|\x{7E3E}|\x{7E43}|\x{7E45}|\x{7E46}|\x{7E4F}|\x{7E52}|\x{7E53}|\x{7E54}|\x{7E55}|\x{7E5A}|\x{7E5E}|\x{7E5F}|\x{7E61}|\x{7E62}|\x{7E69}|\x{7E6A}|\x{7E6B}|\x{7E6D}|\x{7E6F}|\x{7E70}|\x{7E73}|\x{7E78}|\x{7E79}|\x{7E7B}|\x{7E7C}|\x{7E7D}|\x{7E7E}|\x{7E7F}|\x{7E81}|\x{7E87}|\x{7E88}|\x{7E8A}|\x{7E8C}|\x{7E8D}|\x{7E8F}|\x{7E93}|\x{7E96}|\x{7E98}|\x{7E9C}|\x{7F3D}|\x{7F48}|\x{7F4C}|\x{7F70}|\x{7F75}|\x{7F77}|\x{7F85}|\x{7F86}|\x{7F88}|\x{7F8B}|\x{7FA5}|\x{7FA9}|\x{7FD2}|\x{7FEC}|\x{7FF9}|\x{7FFD}|\x{802C}|\x{802E}|\x{8056}|\x{805E}|\x{806F}|\x{8070}|\x{8072}|\x{8073}|\x{8075}|\x{8076}|\x{8077}|\x{8079}|\x{807D}|\x{807E}|\x{8085}|\x{8105}|\x{8108}|\x{811B}|\x{8125}|\x{812B}|\x{8139}|\x{814E}|\x{8156}|\x{8161}|\x{8166}|\x{816A}|\x{816B}|\x{8173}|\x{8178}|\x{8183}|\x{8195}|\x{819A}|\x{81A0}|\x{81A2}|\x{81A9}|\x{81BD}|\x{81BE}|\x{81BF}|\x{81C9}|\x{81CD}|\x{81CF}|\x{81D7}|\x{81D8}|\x{81DA}|\x{81DF}|\x{81E0}|\x{81E2}|\x{81E8}|\x{81FA}|\x{8207}|\x{8208}|\x{8209}|\x{820A}|\x{8259}|\x{8264}|\x{8266}|\x{826B}|\x{8271}|\x{8277}|\x{82BB}|\x{82E7}|\x{8332}|\x{834A}|\x{838A}|\x{8396}|\x{83A2}|\x{83A7}|\x{83EF}|\x{8407}|\x{840A}|\x{842C}|\x{8434}|\x{8435}|\x{8449}|\x{8452}|\x{8457}|\x{8464}|\x{8466}|\x{8477}|\x{8494}|\x{849E}|\x{84BC}|\x{84C0}|\x{84CB}|\x{84EE}|\x{84EF}|\x{84F4}|\x{84FD}|\x{851E}|\x{8523}|\x{8525}|\x{8526}|\x{852D}|\x{8541}|\x{8546}|\x{854E}|\x{8552}|\x{8553}|\x{8555}|\x{8558}|\x{8562}|\x{8569}|\x{856A}|\x{856D}|\x{8577}|\x{8580}|\x{8588}|\x{858A}|\x{858C}|\x{8594}|\x{8598}|\x{859F}|\x{85A6}|\x{85A9}|\x{85B3}|\x{85B4}|\x{85BA}|\x{85CD}|\x{85CE}|\x{85DD}|\x{85E5}|\x{85EA}|\x{85F6}|\x{85F9}|\x{85FA}|\x{8604}|\x{8606}|\x{8607}|\x{860A}|\x{860B}|\x{861A}|\x{861E}|\x{8622}|\x{862D}|\x{863A}|\x{863F}|\x{8646}|\x{8655}|\x{865B}|\x{865C}|\x{865F}|\x{8667}|\x{866F}|\x{86FA}|\x{86FB}|\x{8706}|\x{8721}|\x{8755}|\x{875F}|\x{8766}|\x{8778}|\x{8784}|\x{879E}|\x{87A2}|\x{87AE}|\x{87BB}|\x{87BF}|\x{87C4}|\x{87C8}|\x{87CE}|\x{87E3}|\x{87EC}|\x{87EF}|\x{87F2}|\x{87F6}|\x{87FB}|\x{8801}|\x{8805}|\x{8806}|\x{8810}|\x{8811}|\x{881F}|\x{8823}|\x{8828}|\x{8831}|\x{8836}|\x{883B}|\x{8853}|\x{8855}|\x{885A}|\x{885B}|\x{885D}|\x{889E}|\x{88CA}|\x{88DC}|\x{88DD}|\x{88E1}|\x{88FD}|\x{8907}|\x{890C}|\x{8918}|\x{8932}|\x{8933}|\x{8938}|\x{893B}|\x{8940}|\x{8949}|\x{894F}|\x{8956}|\x{895D}|\x{8960}|\x{8964}|\x{896A}|\x{896C}|\x{896F}|\x{8972}|\x{8974}|\x{8986}|\x{898B}|\x{898E}|\x{898F}|\x{8993}|\x{8996}|\x{8998}|\x{89A1}|\x{89A5}|\x{89A6}|\x{89AA}|\x{89AC}|\x{89AF}|\x{89B2}|\x{89B7}|\x{89BA}|\x{89BC}|\x{89BD}|\x{89BF}|\x{89C0}|\x{89F4}|\x{89F6}|\x{89F8}|\x{8A01}|\x{8A02}|\x{8A03}|\x{8A08}|\x{8A0A}|\x{8A0C}|\x{8A0E}|\x{8A10}|\x{8A11}|\x{8A12}|\x{8A13}|\x{8A15}|\x{8A16}|\x{8A17}|\x{8A18}|\x{8A1B}|\x{8A1D}|\x{8A1F}|\x{8A22}|\x{8A23}|\x{8A25}|\x{8A29}|\x{8A2A}|\x{8A2D}|\x{8A31}|\x{8A34}|\x{8A36}|\x{8A3A}|\x{8A3B}|\x{8A40}|\x{8A41}|\x{8A46}|\x{8A4E}|\x{8A50}|\x{8A51}|\x{8A52}|\x{8A54}|\x{8A55}|\x{8A56}|\x{8A57}|\x{8A58}|\x{8A5B}|\x{8A5E}|\x{8A60}|\x{8A61}|\x{8A62}|\x{8A63}|\x{8A66}|\x{8A69}|\x{8A6B}|\x{8A6C}|\x{8A6D}|\x{8A6E}|\x{8A70}|\x{8A71}|\x{8A72}|\x{8A73}|\x{8A75}|\x{8A7C}|\x{8A7F}|\x{8A84}|\x{8A85}|\x{8A86}|\x{8A87}|\x{8A8C}|\x{8A8D}|\x{8A91}|\x{8A92}|\x{8A95}|\x{8A98}|\x{8A9A}|\x{8A9E}|\x{8AA0}|\x{8AA1}|\x{8AA3}|\x{8AA4}|\x{8AA5}|\x{8AA6}|\x{8AA8}|\x{8AAA}|\x{8AB0}|\x{8AB2}|\x{8AB6}|\x{8AB9}|\x{8ABC}|\x{8ABE}|\x{8ABF}|\x{8AC2}|\x{8AC4}|\x{8AC7}|\x{8AC9}|\x{8ACB}|\x{8ACD}|\x{8ACF}|\x{8AD1}|\x{8AD2}|\x{8AD6}|\x{8AD7}|\x{8ADB}|\x{8ADC}|\x{8ADD}|\x{8ADE}|\x{8AE2}|\x{8AE4}|\x{8AE6}|\x{8AE7}|\x{8AEB}|\x{8AED}|\x{8AEE}|\x{8AF0}|\x{8AF1}|\x{8AF3}|\x{8AF6}|\x{8AF7}|\x{8AF8}|\x{8AFA}|\x{8AFC}|\x{8AFE}|\x{8B00}|\x{8B01}|\x{8B02}|\x{8B04}|\x{8B05}|\x{8B0A}|\x{8B0E}|\x{8B0F}|\x{8B10}|\x{8B14}|\x{8B16}|\x{8B17}|\x{8B19}|\x{8B1A}|\x{8B1B}|\x{8B1D}|\x{8B20}|\x{8B28}|\x{8B2B}|\x{8B2C}|\x{8B33}|\x{8B39}|\x{8B3E}|\x{8B49}|\x{8B4A}|\x{8B4E}|\x{8B4F}|\x{8B54}|\x{8B56}|\x{8B58}|\x{8B59}|\x{8B5A}|\x{8B5C}|\x{8B6B}|\x{8B6F}|\x{8B70}|\x{8B74}|\x{8B77}|\x{8B78}|\x{8B7D}|\x{8B7E}|\x{8B80}|\x{8B8A}|\x{8B8B}|\x{8B8C}|\x{8B8E}|\x{8B92}|\x{8B93}|\x{8B95}|\x{8B96}|\x{8B9C}|\x{8B9E}|\x{8C48}|\x{8C4E}|\x{8C50}|\x{8C6C}|\x{8C76}|\x{8C93}|\x{8C99}|\x{8C9D}|\x{8C9E}|\x{8C9F}|\x{8CA0}|\x{8CA1}|\x{8CA2}|\x{8CA7}|\x{8CA8}|\x{8CA9}|\x{8CAA}|\x{8CAB}|\x{8CAC}|\x{8CAF}|\x{8CB0}|\x{8CB2}|\x{8CB3}|\x{8CB4}|\x{8CB6}|\x{8CB7}|\x{8CB8}|\x{8CBA}|\x{8CBB}|\x{8CBC}|\x{8CBD}|\x{8CBF}|\x{8CC0}|\x{8CC1}|\x{8CC2}|\x{8CC3}|\x{8CC4}|\x{8CC5}|\x{8CC7}|\x{8CC8}|\x{8CCA}|\x{8CD1}|\x{8CD2}|\x{8CD3}|\x{8CD5}|\x{8CD9}|\x{8CDA}|\x{8CDC}|\x{8CDE}|\x{8CDF}|\x{8CE0}|\x{8CE1}|\x{8CE2}|\x{8CE3}|\x{8CE4}|\x{8CE6}|\x{8CE7}|\x{8CEA}|\x{8CEC}|\x{8CED}|\x{8CF0}|\x{8CF4}|\x{8CF5}|\x{8CFA}|\x{8CFB}|\x{8CFC}|\x{8CFD}|\x{8CFE}|\x{8D03}|\x{8D04}|\x{8D05}|\x{8D07}|\x{8D08}|\x{8D0A}|\x{8D0D}|\x{8D0F}|\x{8D10}|\x{8D13}|\x{8D14}|\x{8D16}|\x{8D17}|\x{8D1B}|\x{8D6C}|\x{8D95}|\x{8D99}|\x{8DA8}|\x{8DB2}|\x{8DE1}|\x{8E10}|\x{8E34}|\x{8E4C}|\x{8E55}|\x{8E63}|\x{8E64}|\x{8E7A}|\x{8E7B}|\x{8E82}|\x{8E89}|\x{8E8A}|\x{8E8B}|\x{8E8D}|\x{8E8E}|\x{8E91}|\x{8E92}|\x{8E93}|\x{8E95}|\x{8E9A}|\x{8E9D}|\x{8EA1}|\x{8EA5}|\x{8EA6}|\x{8EAA}|\x{8EC0}|\x{8EC9}|\x{8ECA}|\x{8ECB}|\x{8ECC}|\x{8ECD}|\x{8ECF}|\x{8ED1}|\x{8ED2}|\x{8ED4}|\x{8ED7}|\x{8EDB}|\x{8EDF}|\x{8EE4}|\x{8EE8}|\x{8EEB}|\x{8EF2}|\x{8EF8}|\x{8EF9}|\x{8EFA}|\x{8EFB}|\x{8EFC}|\x{8EFE}|\x{8F03}|\x{8F04}|\x{8F05}|\x{8F07}|\x{8F08}|\x{8F09}|\x{8F0A}|\x{8F12}|\x{8F13}|\x{8F14}|\x{8F15}|\x{8F17}|\x{8F1B}|\x{8F1C}|\x{8F1D}|\x{8F1E}|\x{8F1F}|\x{8F25}|\x{8F26}|\x{8F29}|\x{8F2A}|\x{8F2C}|\x{8F2E}|\x{8F2F}|\x{8F33}|\x{8F38}|\x{8F3B}|\x{8F3E}|\x{8F3F}|\x{8F40}|\x{8F42}|\x{8F44}|\x{8F45}|\x{8F46}|\x{8F49}|\x{8F4D}|\x{8F4E}|\x{8F54}|\x{8F5F}|\x{8F61}|\x{8F62}|\x{8F63}|\x{8F64}|\x{8FA6}|\x{8FAD}|\x{8FAE}|\x{8FAF}|\x{8FB2}|\x{9015}|\x{9019}|\x{9023}|\x{9032}|\x{904B}|\x{904E}|\x{9054}|\x{9055}|\x{9059}|\x{905C}|\x{905E}|\x{9060}|\x{9069}|\x{9072}|\x{9077}|\x{9078}|\x{907A}|\x{907C}|\x{9081}|\x{9084}|\x{9087}|\x{908A}|\x{908F}|\x{9090}|\x{90DF}|\x{90F5}|\x{9106}|\x{9109}|\x{9112}|\x{9114}|\x{9116}|\x{9127}|\x{912D}|\x{9130}|\x{9132}|\x{9134}|\x{9136}|\x{913A}|\x{9147}|\x{9148}|\x{919C}|\x{919E}|\x{91AB}|\x{91AC}|\x{91B1}|\x{91C0}|\x{91C1}|\x{91C3}|\x{91C5}|\x{91CB}|\x{91D0}|\x{91D2}|\x{91D3}|\x{91D4}|\x{91D5}|\x{91D7}|\x{91D8}|\x{91D9}|\x{91DD}|\x{91E3}|\x{91E4}|\x{91E7}|\x{91E9}|\x{91F3}|\x{91F5}|\x{91F7}|\x{91F9}|\x{91FA}|\x{91FE}|\x{9200}|\x{9201}|\x{9203}|\x{9204}|\x{9207}|\x{9208}|\x{9209}|\x{920B}|\x{920D}|\x{9210}|\x{9211}|\x{9212}|\x{9214}|\x{9215}|\x{921E}|\x{9220}|\x{9223}|\x{9225}|\x{9226}|\x{9227}|\x{922E}|\x{922F}|\x{9230}|\x{9232}|\x{9233}|\x{9234}|\x{9237}|\x{9238}|\x{9239}|\x{923A}|\x{923D}|\x{923E}|\x{923F}|\x{9240}|\x{9241}|\x{9245}|\x{9248}|\x{9249}|\x{924B}|\x{924D}|\x{9251}|\x{9255}|\x{9257}|\x{925A}|\x{925B}|\x{925E}|\x{9264}|\x{9266}|\x{9268}|\x{926C}|\x{926D}|\x{9276}|\x{9278}|\x{927A}|\x{927B}|\x{927F}|\x{9280}|\x{9283}|\x{9285}|\x{928D}|\x{9291}|\x{9293}|\x{9296}|\x{9298}|\x{929A}|\x{929B}|\x{929C}|\x{92A0}|\x{92A3}|\x{92A5}|\x{92A6}|\x{92A8}|\x{92A9}|\x{92AA}|\x{92AB}|\x{92AC}|\x{92B1}|\x{92B3}|\x{92B6}|\x{92B7}|\x{92BB}|\x{92BC}|\x{92C1}|\x{92C3}|\x{92C5}|\x{92C7}|\x{92C9}|\x{92CC}|\x{92CF}|\x{92D2}|\x{92D9}|\x{92DD}|\x{92DF}|\x{92E3}|\x{92E4}|\x{92E5}|\x{92E6}|\x{92E8}|\x{92E9}|\x{92EA}|\x{92EE}|\x{92EF}|\x{92F0}|\x{92F1}|\x{92F6}|\x{92F8}|\x{92FC}|\x{9301}|\x{9302}|\x{9304}|\x{9306}|\x{9307}|\x{9308}|\x{930F}|\x{9310}|\x{9312}|\x{9315}|\x{9318}|\x{9319}|\x{931A}|\x{931B}|\x{931F}|\x{9320}|\x{9321}|\x{9322}|\x{9326}|\x{9328}|\x{9329}|\x{932B}|\x{932E}|\x{932F}|\x{9333}|\x{9336}|\x{9338}|\x{9340}|\x{9343}|\x{9344}|\x{9346}|\x{9347}|\x{9348}|\x{934B}|\x{934D}|\x{9354}|\x{9358}|\x{935A}|\x{935B}|\x{9360}|\x{9364}|\x{9365}|\x{9369}|\x{936C}|\x{936E}|\x{9370}|\x{9375}|\x{9376}|\x{937A}|\x{937E}|\x{9382}|\x{9384}|\x{9387}|\x{938A}|\x{9394}|\x{9396}|\x{9398}|\x{939B}|\x{939D}|\x{93A1}|\x{93A2}|\x{93A3}|\x{93A6}|\x{93A7}|\x{93A9}|\x{93AA}|\x{93AC}|\x{93AE}|\x{93AF}|\x{93B0}|\x{93B2}|\x{93B3}|\x{93B5}|\x{93B6}|\x{93B7}|\x{93BF}|\x{93C3}|\x{93C6}|\x{93C7}|\x{93C8}|\x{93C9}|\x{93CC}|\x{93CD}|\x{93D0}|\x{93D1}|\x{93D7}|\x{93D8}|\x{93DC}|\x{93DD}|\x{93DE}|\x{93DF}|\x{93E1}|\x{93E2}|\x{93E4}|\x{93E6}|\x{93E8}|\x{93F0}|\x{93F5}|\x{93F7}|\x{93F9}|\x{93FA}|\x{93FD}|\x{9403}|\x{9404}|\x{940B}|\x{940D}|\x{940E}|\x{940F}|\x{9410}|\x{9412}|\x{9413}|\x{9414}|\x{9418}|\x{9419}|\x{9420}|\x{9425}|\x{9426}|\x{9427}|\x{9428}|\x{942B}|\x{942E}|\x{942F}|\x{9432}|\x{9433}|\x{9435}|\x{9436}|\x{9438}|\x{943A}|\x{943F}|\x{9444}|\x{9448}|\x{944A}|\x{944C}|\x{9452}|\x{9454}|\x{9455}|\x{945E}|\x{9460}|\x{9463}|\x{9465}|\x{946D}|\x{9470}|\x{9471}|\x{9472}|\x{9477}|\x{9479}|\x{947C}|\x{947D}|\x{947E}|\x{947F}|\x{9481}|\x{9577}|\x{9580}|\x{9582}|\x{9583}|\x{9586}|\x{9588}|\x{9589}|\x{958B}|\x{958C}|\x{958D}|\x{958E}|\x{958F}|\x{9590}|\x{9591}|\x{9593}|\x{9594}|\x{9598}|\x{95A1}|\x{95A3}|\x{95A5}|\x{95A8}|\x{95A9}|\x{95AB}|\x{95AC}|\x{95AD}|\x{95B1}|\x{95B6}|\x{95B9}|\x{95BB}|\x{95BC}|\x{95BD}|\x{95BE}|\x{95BF}|\x{95C3}|\x{95C6}|\x{95C8}|\x{95CA}|\x{95CB}|\x{95CC}|\x{95CD}|\x{95D0}|\x{95D2}|\x{95D3}|\x{95D4}|\x{95D5}|\x{95D6}|\x{95DC}|\x{95DE}|\x{95E0}|\x{95E1}|\x{95E4}|\x{95E5}|\x{962A}|\x{9658}|\x{965D}|\x{9663}|\x{9670}|\x{9673}|\x{9678}|\x{967D}|\x{9689}|\x{968A}|\x{968E}|\x{9695}|\x{969B}|\x{96A4}|\x{96A8}|\x{96AA}|\x{96B1}|\x{96B4}|\x{96B8}|\x{96BB}|\x{96CB}|\x{96D6}|\x{96D9}|\x{96DB}|\x{96DC}|\x{96DE}|\x{96E2}|\x{96E3}|\x{96F2}|\x{96FB}|\x{9722}|\x{9727}|\x{973D}|\x{9742}|\x{9744}|\x{9748}|\x{975A}|\x{975C}|\x{9766}|\x{9768}|\x{9780}|\x{978F}|\x{979D}|\x{97BD}|\x{97C1}|\x{97C3}|\x{97C9}|\x{97CB}|\x{97CC}|\x{97CD}|\x{97D3}|\x{97D9}|\x{97DC}|\x{97DE}|\x{97FB}|\x{97FF}|\x{9801}|\x{9802}|\x{9803}|\x{9805}|\x{9806}|\x{9807}|\x{9808}|\x{980A}|\x{980C}|\x{980E}|\x{980F}|\x{9810}|\x{9811}|\x{9812}|\x{9813}|\x{9817}|\x{9818}|\x{981C}|\x{9821}|\x{9824}|\x{9826}|\x{982D}|\x{982E}|\x{9830}|\x{9832}|\x{9834}|\x{9837}|\x{9838}|\x{9839}|\x{983B}|\x{9843}|\x{9846}|\x{984C}|\x{984D}|\x{984E}|\x{984F}|\x{9852}|\x{9853}|\x{9858}|\x{9859}|\x{985B}|\x{985E}|\x{9862}|\x{9865}|\x{9867}|\x{986B}|\x{986C}|\x{986F}|\x{9870}|\x{9871}|\x{9873}|\x{9874}|\x{98A8}|\x{98AD}|\x{98AE}|\x{98AF}|\x{98B0}|\x{98B1}|\x{98B3}|\x{98B6}|\x{98B7}|\x{98B8}|\x{98BA}|\x{98BB}|\x{98BC}|\x{98BE}|\x{98C0}|\x{98C4}|\x{98C6}|\x{98C8}|\x{98DB}|\x{98E0}|\x{98E2}|\x{98E3}|\x{98E5}|\x{98E9}|\x{98EA}|\x{98EB}|\x{98ED}|\x{98EF}|\x{98F2}|\x{98F4}|\x{98FC}|\x{98FD}|\x{98FE}|\x{98FF}|\x{9903}|\x{9904}|\x{9905}|\x{9909}|\x{990A}|\x{990C}|\x{990E}|\x{990F}|\x{9911}|\x{9912}|\x{9913}|\x{9914}|\x{9915}|\x{9916}|\x{9917}|\x{9918}|\x{991A}|\x{991B}|\x{991C}|\x{991E}|\x{9921}|\x{9926}|\x{9928}|\x{992D}|\x{9931}|\x{9933}|\x{9936}|\x{9937}|\x{9938}|\x{993A}|\x{993C}|\x{993E}|\x{993F}|\x{9941}|\x{9943}|\x{9945}|\x{9948}|\x{9949}|\x{994A}|\x{994B}|\x{994C}|\x{9952}|\x{9957}|\x{9958}|\x{995C}|\x{995E}|\x{9962}|\x{99AC}|\x{99AD}|\x{99AE}|\x{99B1}|\x{99B3}|\x{99B4}|\x{99B9}|\x{99C1}|\x{99C3}|\x{99CE}|\x{99D0}|\x{99D1}|\x{99D2}|\x{99D4}|\x{99D5}|\x{99D8}|\x{99D9}|\x{99DA}|\x{99DB}|\x{99DD}|\x{99DF}|\x{99E2}|\x{99E7}|\x{99E9}|\x{99ED}|\x{99F0}|\x{99F1}|\x{99F6}|\x{99F8}|\x{99FB}|\x{99FF}|\x{9A01}|\x{9A02}|\x{9A03}|\x{9A05}|\x{9A0C}|\x{9A0D}|\x{9A0E}|\x{9A0F}|\x{9A14}|\x{9A16}|\x{9A19}|\x{9A1A}|\x{9A1D}|\x{9A1F}|\x{9A20}|\x{9A24}|\x{9A27}|\x{9A2A}|\x{9A2B}|\x{9A2D}|\x{9A2E}|\x{9A30}|\x{9A36}|\x{9A37}|\x{9A38}|\x{9A3E}|\x{9A40}|\x{9A41}|\x{9A42}|\x{9A43}|\x{9A44}|\x{9A45}|\x{9A4A}|\x{9A4B}|\x{9A4C}|\x{9A4D}|\x{9A4F}|\x{9A55}|\x{9A57}|\x{9A5A}|\x{9A5B}|\x{9A5F}|\x{9A62}|\x{9A64}|\x{9A65}|\x{9A66}|\x{9A6A}|\x{9A6B}|\x{9AAF}|\x{9ACF}|\x{9AD2}|\x{9AD4}|\x{9AD5}|\x{9AD6}|\x{9AEE}|\x{9B06}|\x{9B0D}|\x{9B1A}|\x{9B22}|\x{9B25}|\x{9B27}|\x{9B29}|\x{9B2E}|\x{9B31}|\x{9B39}|\x{9B4E}|\x{9B58}|\x{9B5A}|\x{9B5B}|\x{9B5F}|\x{9B62}|\x{9B65}|\x{9B68}|\x{9B6F}|\x{9B74}|\x{9B77}|\x{9B7A}|\x{9B81}|\x{9B83}|\x{9B84}|\x{9B8A}|\x{9B8B}|\x{9B8D}|\x{9B90}|\x{9B91}|\x{9B92}|\x{9B93}|\x{9B9A}|\x{9B9C}|\x{9B9E}|\x{9B9F}|\x{9BA3}|\x{9BA6}|\x{9BAA}|\x{9BAB}|\x{9BAD}|\x{9BAE}|\x{9BB0}|\x{9BB3}|\x{9BB6}|\x{9BB8}|\x{9BBA}|\x{9BC0}|\x{9BC1}|\x{9BC4}|\x{9BC6}|\x{9BC7}|\x{9BC9}|\x{9BCA}|\x{9BD2}|\x{9BD4}|\x{9BD5}|\x{9BD6}|\x{9BD7}|\x{9BDB}|\x{9BDD}|\x{9BE1}|\x{9BE2}|\x{9BE4}|\x{9BE7}|\x{9BE8}|\x{9BEA}|\x{9BEB}|\x{9BF1}|\x{9BF4}|\x{9BF6}|\x{9BF7}|\x{9BFD}|\x{9BFF}|\x{9C01}|\x{9C02}|\x{9C03}|\x{9C06}|\x{9C08}|\x{9C09}|\x{9C0C}|\x{9C0D}|\x{9C0F}|\x{9C12}|\x{9C13}|\x{9C1C}|\x{9C1F}|\x{9C20}|\x{9C23}|\x{9C24}|\x{9C25}|\x{9C27}|\x{9C28}|\x{9C29}|\x{9C2D}|\x{9C2E}|\x{9C31}|\x{9C32}|\x{9C33}|\x{9C35}|\x{9C37}|\x{9C39}|\x{9C3A}|\x{9C3B}|\x{9C3C}|\x{9C3E}|\x{9C42}|\x{9C45}|\x{9C47}|\x{9C48}|\x{9C49}|\x{9C52}|\x{9C54}|\x{9C56}|\x{9C57}|\x{9C58}|\x{9C5D}|\x{9C5F}|\x{9C60}|\x{9C63}|\x{9C64}|\x{9C67}|\x{9C68}|\x{9C6D}|\x{9C6E}|\x{9C6F}|\x{9C72}|\x{9C77}|\x{9C78}|\x{9C7A}|\x{9CE5}|\x{9CE7}|\x{9CE9}|\x{9CF2}|\x{9CF3}|\x{9CF4}|\x{9CF6}|\x{9CF7}|\x{9CFC}|\x{9CFE}|\x{9D03}|\x{9D06}|\x{9D07}|\x{9D09}|\x{9D12}|\x{9D15}|\x{9D17}|\x{9D1B}|\x{9D1C}|\x{9D1D}|\x{9D1E}|\x{9D1F}|\x{9D23}|\x{9D26}|\x{9D28}|\x{9D2F}|\x{9D30}|\x{9D32}|\x{9D34}|\x{9D37}|\x{9D3B}|\x{9D3F}|\x{9D41}|\x{9D42}|\x{9D43}|\x{9D50}|\x{9D51}|\x{9D52}|\x{9D53}|\x{9D5A}|\x{9D5C}|\x{9D5D}|\x{9D60}|\x{9D61}|\x{9D6A}|\x{9D6C}|\x{9D6E}|\x{9D6F}|\x{9D72}|\x{9D77}|\x{9D7E}|\x{9D84}|\x{9D87}|\x{9D89}|\x{9D8A}|\x{9D92}|\x{9D93}|\x{9D96}|\x{9D97}|\x{9D98}|\x{9D9A}|\x{9DA1}|\x{9DA5}|\x{9DA9}|\x{9DAA}|\x{9DAC}|\x{9DAF}|\x{9DB1}|\x{9DB2}|\x{9DB4}|\x{9DB9}|\x{9DBA}|\x{9DBB}|\x{9DBC}|\x{9DBF}|\x{9DC1}|\x{9DC2}|\x{9DC8}|\x{9DCA}|\x{9DD3}|\x{9DD4}|\x{9DD6}|\x{9DD7}|\x{9DD9}|\x{9DDA}|\x{9DE5}|\x{9DE6}|\x{9DE8}|\x{9DEB}|\x{9DEF}|\x{9DF2}|\x{9DF3}|\x{9DF8}|\x{9DF9}|\x{9DFA}|\x{9DFD}|\x{9DFF}|\x{9E02}|\x{9E07}|\x{9E0B}|\x{9E0C}|\x{9E0F}|\x{9E15}|\x{9E18}|\x{9E1A}|\x{9E1B}|\x{9E1D}|\x{9E1E}|\x{9E75}|\x{9E79}|\x{9E7A}|\x{9E7C}|\x{9E7D}|\x{9E97}|\x{9EA5}|\x{9EA8}|\x{9EA9}|\x{9EB2}|\x{9EB5}|\x{9EBC}|\x{9EBD}|\x{9EC3}|\x{9ECC}|\x{9EDE}|\x{9EE8}|\x{9EF2}|\x{9EF6}|\x{9EF7}|\x{9EFD}|\x{9EFF}|\x{9F09}|\x{9F34}|\x{9F4A}|\x{9F4B}|\x{9F4E}|\x{9F4F}|\x{9F52}|\x{9F54}|\x{9F55}|\x{9F57}|\x{9F59}|\x{9F5C}|\x{9F5F}|\x{9F60}|\x{9F61}|\x{9F66}|\x{9F6A}|\x{9F6C}|\x{9F72}|\x{9F76}|\x{9F77}|\x{9F8D}|\x{9F8E}|\x{9F90}|\x{9F91}|\x{9F94}|\x{9F95}|\x{9F9C}|\x{9FAD}|\x{9FAF}|\x{9FC1}|\x{9FD0}|\x{9FD2}|\x{20325}|\x{203E2}|\x{20786}|\x{2080E}|\x{21114}|\x{21123}|\x{2114F}|\x{2146D}|\x{214FE}|\x{217B5}|\x{21839}|\x{21883}|\x{21B89}|\x{21BA3}|\x{21FB1}|\x{228DA}|\x{228ED}|\x{22DAB}|\x{22DEE}|\x{22E7F}|\x{2364E}|\x{23755}|\x{237BB}|\x{23832}|\x{23BF4}|\x{23FB7}|\x{23FC9}|\x{24063}|\x{2448E}|\x{24ABA}|\x{24AE9}|\x{24CF8}|\x{24E2B}|\x{25303}|\x{25565}|\x{25585}|\x{258A2}|\x{25A10}|\x{25D43}|\x{25D4A}|\x{25E20}|\x{25F3D}|\x{25F56}|\x{25FCA}|\x{26085}|\x{260C4}|\x{26888}|\x{268CE}|\x{26ABD}|\x{27525}|\x{27717}|\x{27735}|\x{2775E}|\x{27A59}|\x{27CDF}|\x{27D73}|\x{27D94}|\x{27DA7}|\x{28123}|\x{2814D}|\x{281C1}|\x{281DE}|\x{2820A}|\x{2820C}|\x{282B0}|\x{282B8}|\x{282BB}|\x{282E2}|\x{283AE}|\x{283E0}|\x{283E5}|\x{2893B}|\x{2895B}|\x{289AB}|\x{289DC}|\x{289F1}|\x{28AD2}|\x{28B82}|\x{28BC5}|\x{28CD1}|\x{28CD5}|\x{28D17}|\x{28D69}|\x{28D78}|\x{28D80}|\x{28D8F}|\x{28DAE}|\x{28DB2}|\x{28DF2}|\x{28F4F}|\x{293A2}|\x{293EA}|\x{294E3}|\x{295C0}|\x{29600}|\x{2961D}|\x{29639}|\x{2963A}|\x{29648}|\x{2969B}|\x{296A5}|\x{296B5}|\x{296C6}|\x{296E9}|\x{29707}|\x{29726}|\x{29735}|\x{29754}|\x{29784}|\x{297A6}|\x{297AF}|\x{297D0}|\x{29834}|\x{2987A}|\x{298A1}|\x{298B4}|\x{298B8}|\x{298BE}|\x{298CF}|\x{298D1}|\x{298FA}|\x{2990A}|\x{29919}|\x{29932}|\x{29938}|\x{29944}|\x{29947}|\x{29949}|\x{29951}|\x{299C6}|\x{29B59}|\x{29BF3}|\x{29C00}|\x{29CE4}|\x{29D69}|\x{29D79}|\x{29D98}|\x{29DB0}|\x{29DB1}|\x{29DF0}|\x{29E03}|\x{29E26}|\x{29FEA}|\x{2A026}|\x{2A03E}|\x{2A048}|\x{2A056}|\x{2A086}|\x{2A0CD}|\x{2A0CF}|\x{2A106}|\x{2A115}|\x{2A1F3}|\x{2A2FF}|\x{2A535}|\x{2A600}|\x{2A62F})/u',$input) ){
		return true;
	}
	else {
		return false;
	}
}

function hasKanji(string $input)
{
	if ( preg_match('/\p{Han}/u',$input) ){
		return true;
	}
	else {
		return false;
	}
}

function hasHiragana(string $input)
{
	if ( preg_match('/\p{Hiragana}/u',$input) ){
		return true;
	}
	else {
		return false;
	}
}

function hasKatakana(string $input)
{
	if ( preg_match('/\p{Katakana}/u',$input) ){
		return true;
	}
	else {
		return false;
	}
}

● 実行結果

================比特币
漢字を含みます。簡体字を含みます。

================以创纪录的水平扩容并将保持继续
漢字を含みます。簡体字を含みます。

================あいうえお
ひらがなを含みます。

================細野晴臣
漢字を含みます。繁体字を含みます。

================今日はとても暖かい1日となりました
ひらがなを含みます。漢字を含みます。

================日本語のテストを行っています。
ひらがなを含みます。カタカナを含みます。漢字を含みます。繁体字を含みます。

● 参考

文字コード考え方から理解するUnicodeとUTF-8の違い | ギークを目指して

繁体字と簡体字と日本語を区別する - Qiita

No.1495
04/22 15:11

edit

PHPのCarbonで「次の20日」を取得する

● PHPのCarbonで「次の20日」を取得する

    /**
     * 次の 20日 を取得する
     *
     * 例: 4/15日にこのメソッドを実行 -> 4/20が返る
     * 例: 4/21日にこのメソッドを実行 -> 5/20が返る
     *
     *
     * なお、20日に実行した場合は当日が返る
     *
     * 例: 4/20日にこのメソッドを実行 -> 4/20が返る
     *
     */
    protected function getNextNthDay( \Carbon\Carbon $arg_dt , $day_no=20 )
    {
        if($arg_dt->day > $day_no ){
            $arg_dt->firstOfMonth()->addMonthsNoOverflow()->addDay( $day_no-1 );
        } else {
            // 今月の20日をセット
            $arg_dt->firstOfMonth()->addDay( $day_no-1 );
        }
        return $arg_dt;
    }

使い方( Laravel で dump してみる例 )

$dt_next_nth_day = $this->getNextNthDay( new \Carbon\Carbon('2019-04-21') );
dump( '2019-04-21 の次の 「20日」は', $dt_next_nth_day); echo "<br>";
No.1487
04/17 13:07

edit

ファイルサイズを KB , MB にフォーマットする

BCMath PHP拡張 が必要です。サーバにあるかどうか確認しておきましょう

● インストール

composer require gabrielelana/byte-units

● フォーマット方法

ByteUnits\bytes(filesize('picture.jpg'))->format();
No.1469
09/24 16:56

edit

PHP Composer 現在インストール中のパッケージ一覧を表示する

● PHP Composer 現在インストール中のパッケージ一覧を表示する(ローカル)

cd <my_dir>
composer show

● PHP Composer 現在インストール中のパッケージ一覧を表示する(グローバル)

composer global show
No.1437
02/05 09:45

edit

PHPでファイルの mime type を取得する

● PHPでファイルの mime type を取得する

$finfo = new \finfo(FILEINFO_MIME_TYPE);
$mime_type = $finfo->file(Sfile_path);
No.1435
02/04 10:49

edit

PHPのCarbonで元号(明治、大正、昭和、平成)を表示させる

● PHPのCarbonで元号(明治、大正、昭和、平成)を含む日付を表示させる(0埋め)

date_default_timezone_set('Asia/Tokyo');
setlocale(LC_TIME, 'ja_JP.utf8');
$format = '%EC%Ey年%m月%d日';
echo \Carbon\Carbon::now()->formatLocalized($format);
平成31年02月08日

● PHPのCarbonで元号(明治、大正、昭和、平成)を含む日付を表示させる(0で埋めない)

date_default_timezone_set('Asia/Tokyo');
setlocale(LC_TIME, 'ja_JP.utf8');
$format = '%EC%Ey年%-m月%-d日';
echo \Carbon\Carbon::now()->formatLocalized($format);
平成31年2月8日
No.1432
01/31 15:38

edit

PHPで(symfony/yaml)を使ってYAMLをパースする

PHPでは hjson(コメント付きjson) がいまいち使えない( laktak/hjson ではマルチバイトでエラーが出るみたい。。。)なので、
設定ファイルにコメントを入れたい時はYAMLを使用します。

● symfony/yaml

https://packagist.org/packages/symfony/yaml

インストール

composer require symfony/yaml

使い方

<?php
require __DIR__ . '/vendor/autoload.php';
$input = '{foo: "bar"}';
$result = \Symfony\Component\Yaml\Yaml::parse($input);
var_dump($result);

パースすると配列になります。

配列をオブジェクトに変換する

$result = json_decode(json_encode($result));

PHPの配列を yaml フォーマットにする

$yaml = \Symfony\Component\Yaml\Yaml::dump($array,99);

引数は以下の通り。

    /**
     * Dumps a PHP value to a YAML string.
     *
     * The dump method, when supplied with an array, will do its best
     * to convert the array into friendly YAML.
     *
     * @param mixed $input  The PHP value
     * @param int   $inline The level where you switch to inline YAML
     * @param int   $indent The amount of spaces to use for indentation of nested nodes
     * @param int   $flags  A bit field of DUMP_* constants to customize the dumped YAML string
     *
     * @return string A YAML string representing the original PHP value
     */
    public static function dump($input, int $inline = 2, int $indent = 4, int $flags = 0): string
    {
        $yaml = new Dumper($indent);
        return $yaml->dump($input, $inline, 0, $flags);

● YAMLのヒアドキュメント

( 半角スペース1つ と | )

view_data: |
    1行目です。
    2行目です。
    3行目です。
No.1430
06/11 09:37

edit

Pusherを使ってリアルタイム通知を行う

● Pusherを使ってリアルタイム通知を行う

● 1. PUSHER へユーザー登録する

https://pusher.com/

( 20万通知/日 まで 無料プランで使用することができます )

https://pusher.com/channels/pricing

● 2. composer から 「pusher/pusher-php-server」パッケージをインストールする

composer require pusher/pusher-php-server

● 3. 通知を受ける画面を作成して表示する

pusher_notification.html

<!DOCTYPE html>
<head>
  <title>Pusher Test</title>
  <script src="https://js.pusher.com/4.3/pusher.min.js"></script>
  <script>
    // Enable pusher logging - don't include this in production
    Pusher.logToConsole = true;
    var pusher = new Pusher('XXXXXXXXXXXXXXXXXX', { // pusher から 配布された id をここに記述します。
      cluster: 'ap3',
      forceTLS: true
    });
    var channel = pusher.subscribe('my-channel');
    channel.bind('my-event', function(data) {
      alert(JSON.stringify(data));
    });
  </script>
</head>
<body>
  <h1>Pusher Test</h1>
  <p>
    Try publishing an event to channel <code>my-channel</code>
    with event name <code>my-event</code>.
  </p>
</body>

● 4. 通知を追加するphpを作成して表示する

pusher.php

<?php
require __DIR__ . '/vendor/autoload.php';

$options = array(
    'cluster' => 'ap3',
    'useTLS' => true,
);
$pusher = new Pusher\Pusher(
    'AAAAA',
    'BBBBB',
    'CCCCC',
    $options
);

$dt = new DateTime();
$data['message'] = 'hello world' . $dt->format('Y-m-d H:i:s');
$pusher->trigger('my-channel', 'my-event', $data);

これだけでOKです。
これで、ブラウザで pusher_notification.html を 開いた状態で pusher.php を更新するだけで、通知が表示されます。
(例では alert で表示しているので この部分を new Notification() に変更するだけでOKです。 )

No.1418
01/16 14:41

edit

PHPで特定のHTMLタグを取り除く

● PHPで特定のHTMLタグを取り除く

PHPで特定のHTMLタグを取り除いて、プレーンなテキストにするには次のパッケージを利用すると簡単にできます。

● athoshun/html-filter

https://packagist.org/packages/athoshun/html-filter

1. athoshun/html-filterのインストール

composer require athoshun/html-filter

2. 使い方

$config に残すタグや属性をセットして $filter で除去します。
<?php

$config = new \AthosHun\HTMLFilter\Configuration();
$config->allowTag("p")
       ->allowAttribute("a", "title")
       ->allowAttribute("a", "href", "|^https?://.*\$|");

$filter = new \AthosHun\HTMLFilter\HTMLFilter();

$html = <<<HTML
Lorem ipsum <em>dolor</em> sit amet
<p>
    Consectetur <a href="http://example.com" title="hey!">adipisicing</a>
    <a href="javascript:alert(42)" onclick="alert(42)">elit</a>.
</p>
HTML;

print $filter->filter($config, $html);

3. 結果

Lorem ipsum dolor sit amet
<p>
    Consectetur <a href="http://example.com" title="hey!">adipisicing</a>
    <a>elit</a>.
</p>
No.1391
12/13 09:23

edit

PHP の PsySH を使ってコマンドを調べる / PsySH を使って変数の中身を表示させる

● PsySH

https://psysh.org/

PsySHはPHPのREPLライブラリです。 チャットをしているかのようにPHPを実行できます。

● PsySHのインストール

composer g require psy/psysh:@stable

● どこからでも利用できるようにする (MacOSの場合)

パス $HOME/.composer/vendor/bin を追加します 例

export PATH="$HOME/.composer/vendor/bin:$PATH"

● PsySHを実行してphpのメソッド(関数)を調べる

1. PsySHを実行する

./vendor/bin/psysh

パスを設定している場合は psysh だけでOKです。

2. メソッドを調べる

「あの配列の関数なんだったかな... array ナントカのやつ」 というときは

ar を押してから TABを2回押す

すると、一覧が表示されます。

PsySHのPHP関数一覧表示

● PsySHを使ってデバッグする

もういちいち print_r や var_dump をして die しなくてもOKです。

1. autoload を読み込ませておく

require_once('./vendor/autoload.php');

2. デバッグしたい位置にこちらを記述

eval(\Psy\sh());

すると、PsySHが立ち上がるので
$ を押してから TABを2回押す
これで、変数一覧が表示されます。
後は変数を指定すれば中身がみれます。

3. 実際の使用例

require_once('./vendor/autoload.php');
$hogehoge = [
	'test' => 'test' ,
	'asdfasfsdafsdaf' => 'test' ,
];
$fugafuga = function($str) use(&$no) {
  return $no++;
};
eval(\Psy\sh());

PsySHが立ち上がったら、$ を押してから TABを2回押す

すると、一覧が表示されます。

プログラムの変数一覧表示

続けて 変数名を指定すると変数の中身が表示されます。

変数の中身を表示

● PsySHを終了させる

quit

または

exit
添付ファイル1
psysh.png ( 34.1 KBytes ) ダウンロード
添付ファイル2
添付ファイル3
No.1380
11/28 10:33

edit

添付ファイル

PHPで cURLやfile_get_contents の代わりに GUZZLE を使用してWEBサイトを取得 / 送信する

PHPで WEBサイトを取得するには昔は「cURL」や「file_get_contents」 をしていましたが、GUZZLEを使いましょう。

● GUZZLE

https://packagist.org/packages/guzzlehttp/guzzle

composer require guzzlehttp/guzzle

・GUZZLEを使って GETメソッドでURLからコンテンツを取得する

$url = 'https://YOUR-WEB-SITE/';
$client = new \GuzzleHttp\Client();
$res = $client->request('GET', $url, [
    'verify' => false ,
    'headers' => [
        'User-Agent' => 'YOUR-USER-AGENT',
    ] ,
]);
$html = $res->getBody()->getContents();
echo $html;

・GUZZLEを使って POSTメソッドでフォームパラメーターを送信する

$url = 'https://YOUR-WEB-SITE/';
$client = new \GuzzleHttp\Client(
    [\GuzzleHttp\RequestOptions::VERIFY => false]
);
$client->request('POST', $url, [
    'form_params' => [
        'foo' => 'bar',
        'hogehoge' => ['hoge1', 'hoge2']
    ]
]);

● guzzle の ミドルウェアを使って機能を強化する

https://engineering.otobank.co.jp/entry/2019/07/01/150927

参考サイト : https://qiita.com/yousan/items/2a4d9eac82c77be8ba8b

No.1378
11/11 23:12

edit

PHPで長い英文の文章を単語の途中で切らずに分割する

● PHPで長い英文の文章を単語の途中で切らずに分割する

・vanderlee/php-sentence

https://packagist.org/packages/vanderlee/php-sentence

composer require vanderlee/php-sentence

使い方 例:9500バイト以上の英文を分けて配列で返します。

require 'vendor/autoload.php';

function split_english_text($text = '', $bytes = 9500) {
	$split_text_arrray = [];
	if (mb_strlen($text) > $bytes) {
		$Sentence = new Sentence;
		$sentences = $Sentence->split($text);
		$i = 0;
		foreach ($sentences as $v) {
			if (mb_strlen($split_text_arrray[$i]) >= $bytes) {
				$i++;
				$split_text_arrray[$i] .= $v;
			} else {
				$split_text_arrray[$i] .= $v;
			}
		}
	} else {
		$split_text_arrray[0] = $text;
	}
	return $split_text_arrray;
}

$text = <<< DOC_END
(ここに長い英文を入れます)
DOC_END;

$split_text_arrray = split_english_text($text);
print_r( $split_text_arrray );

長い文章を約9500バイト毎に配列にします。

No.1372
11/20 12:21

edit

UTF-8 の クォーテーションを正規化する

● UTF-8 の クォーテーションをPHPでasciiに正規化する

左クォーテーションマーク「 “ 」(見にくいですが、クォーテーションの開始記号です)などを ascii 範囲に正規化するルーチンです。

引用元 : https://goo.gl/P2sgzp

$chr_map = array(
   // Windows codepage 1252
   "\xC2\x82" => "'", // U+0082⇒U+201A single low-9 quotation mark
   "\xC2\x84" => '"', // U+0084⇒U+201E double low-9 quotation mark
   "\xC2\x8B" => "'", // U+008B⇒U+2039 single left-pointing angle quotation mark
   "\xC2\x91" => "'", // U+0091⇒U+2018 left single quotation mark
   "\xC2\x92" => "'", // U+0092⇒U+2019 right single quotation mark
   "\xC2\x93" => '"', // U+0093⇒U+201C left double quotation mark
   "\xC2\x94" => '"', // U+0094⇒U+201D right double quotation mark
   "\xC2\x9B" => "'", // U+009B⇒U+203A single right-pointing angle quotation mark

   // Regular Unicode     // U+0022 quotation mark (")
                          // U+0027 apostrophe     (')
   "\xC2\xAB"     => '"', // U+00AB left-pointing double angle quotation mark
   "\xC2\xBB"     => '"', // U+00BB right-pointing double angle quotation mark
   "\xE2\x80\x98" => "'", // U+2018 left single quotation mark
   "\xE2\x80\x99" => "'", // U+2019 right single quotation mark
   "\xE2\x80\x9A" => "'", // U+201A single low-9 quotation mark
   "\xE2\x80\x9B" => "'", // U+201B single high-reversed-9 quotation mark
   "\xE2\x80\x9C" => '"', // U+201C left double quotation mark
   "\xE2\x80\x9D" => '"', // U+201D right double quotation mark
   "\xE2\x80\x9E" => '"', // U+201E double low-9 quotation mark
   "\xE2\x80\x9F" => '"', // U+201F double high-reversed-9 quotation mark
   "\xE2\x80\xB9" => "'", // U+2039 single left-pointing angle quotation mark
   "\xE2\x80\xBA" => "'", // U+203A single right-pointing angle quotation mark
);
$chr = array_keys  ($chr_map); // but: for efficiency you should
$rpl = array_values($chr_map); // pre-calculate these two arrays
$str = str_replace($chr, $rpl, html_entity_decode($str, ENT_QUOTES, "UTF-8"));
No.1371
11/20 11:54

edit

PHPでMicrosoft (Azure) Translator text を使って翻訳する

1. Azureアカウントを用意する

アカウントの作成はこちらのページがとてもわかりやすいのでこちらを参照してください
https://qiita.com/TakeshiNickOsanai/items/a8039ba8d558f7c8a05e

2. パッケージ matthiasnoback/microsoft-translator をインストールする

composer require matthiasnoback/microsoft-translator

3. PHPで翻訳を実行する

use Buzz\Browser;
use MatthiasNoback\MicrosoftOAuth\AzureTokenProvider;
use MatthiasNoback\MicrosoftTranslator\MicrosoftTranslator;

$browser = new Browser();
$azureKey = '[YOUR-AZURE-SUBSCRIPTION-KEY]';
$accessTokenProvider = new AzureTokenProvider($browser, $azureKey);
$translator = new MicrosoftTranslator($browser, $accessTokenProvider);
$translatedString = $translator->translate('This is a test', 'ja', 'en');
echo $translatedString

これだけでAPIによる機械翻訳が出来ます。

4. Azure Translator text API の価格

プランによって価格が変わります。 一番安いのは「Free」。無料です。

https://azure.microsoft.com/ja-jp/pricing/details/cognitive-services/translator-text-api/

なお Microsoftに問い合わせたところ、スペースも1文字に数えられると言う事です。
文字数カウント - Translator Text API | Microsoft Docs

・「Free」 毎月 200 万文字無料
・「S1」 100万文字あたり ¥1,120 (従量課金制) ( 200万文字無料枠がついてくるわけではない)
・「S2」 最大2億 5000万文字 ¥230,160/毎月
・「S3」 最大10億文字 ¥672,000/毎月
・「S4」 最大100億文字 ¥5,040,000/毎月

S4の料金が凄いですが、無料アカウントが自動で有料アカウントになる事はありません。
(「Free」のプランでは200万文字以上翻訳しようとするとエラーとなります。
なので200万文字を超えることがあらかじめわかっている場合は S1 以上にしておく必要があります。)
なおアカウント作成には本人確認のため(!) クレジットカードが必要です。

No.1343
11/26 17:01

edit

PHPで衝突しにくいユニークなID(ハッシュ)uuidを生成する

● uuidより短いHashid を使用するにはこちら

https://packagist.org/packages/vinkla/hashids

衝突しにくいユニークなID(ハッシュ)を生成したい時UUIDを使うことがありますが、PHPでは簡単に生成できます。

● ramsey/uuid のインストール

composer require ramsey/uuid

● uuidの生成

<?php
require 'vendor/autoload.php';

use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\Exception\UnsatisfiedDependencyException;

try {

    // Generate a version 1 (time-based) UUID object
    $uuid1 = Uuid::uuid1();
    echo $uuid1->toString() . "\n"; // i.e. e4eaaaf2-d142-11e1-b3e4-080027620cdd

    // Generate a version 3 (name-based and hashed with MD5) UUID object
    $uuid3 = Uuid::uuid3(Uuid::NAMESPACE_DNS, 'php.net');
    echo $uuid3->toString() . "\n"; // i.e. 11a38b9a-b3da-360f-9353-a5a725514269

    // Generate a version 4 (random) UUID object
    $uuid4 = Uuid::uuid4();
    echo $uuid4->toString() . "\n"; // i.e. 25769c6c-d34d-4bfe-ba98-e0ee856f3e7a

    // Generate a version 5 (name-based and hashed with SHA1) UUID object
    $uuid5 = Uuid::uuid5(Uuid::NAMESPACE_DNS, 'php.net');
    echo $uuid5->toString() . "\n"; // i.e. c4a760a8-dbcf-5254-a0d9-6a4474bd1b62

} catch (UnsatisfiedDependencyException $e) {

    // Some dependency was not met. Either the method cannot be called on a
    // 32-bit system, or it can, but it relies on Moontoast\Math to be present.
    echo 'Caught exception: ' . $e->getMessage() . "\n";

}

● uuidを短い文字列に変換する

例えば バージョン4の uuid だと 25769c6c-d34d-4bfe-ba98-e0ee856f3e7a のような文字列になります。
これを短くしてみましょう。

● pascaldevink/shortuuid のインストール

composer require pascaldevink/shortuuid

● uuidを短くする(そして戻す)

version4 の uuidを取得し、その後短く変換し、その後戻して表示します。

use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\Exception\UnsatisfiedDependencyException;
use PascalDeVink\ShortUuid\ShortUuid;
echo 'UUID(version 4)';
$uuid4 = Uuid::uuid4();
dump( $uuid4->toString() );

echo 'short UUID(encoded)';
$shortuuid = new ShortUuid();
$su_string = $shortuuid->encode($uuid4);
dump( $su_string );

echo 'UUID(decoded)';
dump( $shortuuid->decode($su_string)->toString() );

( dump 関数は各自ご用意を。なければ echo で置き換えてください。 )

結果

● Laravel で uuid を使用する

Laravel 5.6 以降なら次のメソッドが使用できます

Str::uuid();
Str::orderedUuid();
添付ファイル1
No.1319
05/23 15:57

edit

添付ファイル

PHP 7.2 で発生する「 Function create_function() is deprecated」エラーに対処する

PHP 7.2 からは create_function が内部でeval()を実行していて、セキュリティ上危ないということで廃止され、エラー表示となります。 そこで以下のようにクロージャで置き換えます。

例:create_function() を クロージャで置き換える

$v = preg_replace_callback('/\[?(https?:\/\/[^ ^ ]+)(:title=([^\]]*))?\]?/',
	create_function('$m', '
		return "<a href=\"{$m[1]}\" target=\"_blank\" >"
		. (isset($m[3]) ? $m[3] : $m[1] )
		. "</a>";
	'),
$v);

   ↓

$v = preg_replace_callback('/\[?(https?:\/\/[^ ^ ]+)(:title=([^\]]*))?\]?/',
	function ($m) {
		return "<a href=\"{$m[1]}\" target=\"_blank\" >" . (isset($m[3]) ? $m[3] : $m[1]) . "</a>";
	},
$v);

クロージャ内に変数を渡す場合は set を使用して渡します。

No.1292
09/05 09:14

edit

エラー対処

PHPでハッシュの配列を検索する

PHPでよくあるこういうデータ

$data = [
  0 => [
    "name" => "client" ,
    "type" => "string" ,
    "arguments" => [] ,
    "options" => [
      "nullable" => false
    ]
  ] ,
  1 => [
    "name" => "company" ,
    "type" => "string" ,
    "arguments" => [] ,
    "options" => [] ,
  ] ,
  2 => [
    "name" => "addr1" ,
    "type" => "string" ,
    "arguments" => [
      0 => "12"
    ] ,
    "options" => [
      "nullable" => true
    ] ,
  ] ,
  3 => [
    "name" => "addr2" ,
    "type" => "text" ,
    "arguments" => [] ,
    "options" => [
      "nullable" => true
    ] ,
  ]
];

こういうデータから検索を行い、マッチするデータをすべて取得します。

・1. PHPでハッシュの配列から「name が "addr1" のデータ」を取得

$data_selected = array_filter($data, function($hash){
  return ( @$hash['name'] === "addr1" );
});
print_r($data_selected);

・1. 結果

Array
(
    [2] => Array
        (
            [name] => addr1
            [type] => string
            [arguments] => Array
                (
                    [0] => 12
                )

            [options] => Array
                (
                    [nullable] => 1
                )

        )

)

・2. PHPでハッシュの配列から「name が "addr" で始まるデータ( addr1 , addr2 など)」を取得

$data_selected = array_filter($data, function($hash){
  return ( preg_match("/^addr.+/",@$hash['name']) );
});
print_r($data_selected);

・2. 結果

Array
(
    [2] => Array
        (
            [name] => addr1
            [type] => string
            [arguments] => Array
                (
                    [0] => 12
                )

            [options] => Array
                (
                    [nullable] => 1
                )

        )

    [3] => Array
        (
            [name] => addr2
            [type] => text
            [arguments] => Array
                (
                )

            [options] => Array
                (
                    [nullable] => 1
                )

        )

)

・3. PHPでハッシュの配列から「"options" => [ "nullable" => true ] のデータ」を取得

/*
  "options" => [
    "nullable" => true
  ] ,
  のデータを取得
*/
$data_selected = array_filter($data, function($hash){
  return ( @$hash['options']['nullable'] === true );
});
print_r($data_selected);

・3. 結果

Array
(
    [2] => Array
        (
            [name] => addr1
            [type] => string
            [arguments] => Array
                (
                    [0] => 12
                )

            [options] => Array
                (
                    [nullable] => 1
                )

        )

    [3] => Array
        (
            [name] => addr2
            [type] => text
            [arguments] => Array
                (
                )

            [options] => Array
                (
                    [nullable] => 1
                )

        )

)
No.1284
08/06 14:03

edit

PHPのログクラスmonolog を 使用する

● monolog のインストール

composer require monolog/monolog

● monolog のセッティング

次のようにしてセットしておきます。
以下の例では ./log/error.log にログを吐き出すようにセットしています。(ローテーションなし)
コンストラクタにでも記述しておくといいでしょう。

use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Formatter\LineFormatter;
private $monolog;
// monolog setting
$this->monolog = new Logger('mylog');
$log_formatter = new LineFormatter("[%datetime%] %level_name%: %message% %context% %extra%\n");
$log_handler = new StreamHandler('log/app.log', Logger::DEBUG);
$log_handler->setFormatter($log_formatter);
$this->monolog->pushHandler($log_handler);

● ログの書き込み

次の7種類のログを書き出すことができます (下に行くほど重要)

$this->monolog->debug('ログテスト');
$this->monolog->info('ログテスト');
$this->monolog->notice('ログテスト');
$this->monolog->warning('ログテスト');
$this->monolog->error('ログテスト');
$this->monolog->critical('ログテスト');
$this->monolog->alert('ログテスト');
$this->monolog->emergency('ログテスト');

● monolog のローテーション

monologのローテーションを行うには最初のセッティングのところでローテーションハンドラを指定します。 (例 : RotatingFileHandler を呼び出しています。 log/app-2018-07-11.log のように日付ごとにログが作成されます)

// monolog setting
$this->monolog = new Logger('mylog');
$log_formatter = new LineFormatter("[%datetime%] %level_name%: %message% %context% %extra%\n");
$log_handler = new RotatingFileHandler('log/app.log', 0, Logger::DEBUG, true, 0664);
$log_handler->setFormatter($log_formatter);
$this->monolog->pushHandler($log_handler);

● ログハンドラの種類

StreamHandler			: 任意のログファイルにログを保存する 
RotatingFileHandler	: 日付でログファイルをローテーションする
SyslogHandler			: Syslogに吐く
SwiftMailerHandler	: メールで通知する
MongoDBHandler			: NoSQLにログを格納するハンドラ、
FirePHPHandler			: FireBugにログを出力する
ChromePHPHandler		: Chromeにログを出力する
FingersCrossedHandler		: ログを貯めておいて、危険なレベルのログ出力が来たタイミングでログを出力する

monologのログハンドラの種類
https://github.com/Seldaek/monolog/blob/master/doc/02-handlers-formatters-processors.md

No.1272
11/09 10:24

edit

PHPで大きな値の16進数を10進数に変換する

● PHPで大きな値の16進数を10進数に変換する

通常 hexdec() を使用しますが、大きい値は float で帰ってくるのでその処理をする必要があります。

function bchexdec($hex)
{
    $dec = 0;
    $len = strlen($hex);
    for ($i = 1; $i <= $len; $i++) {
        $dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i))));
    }
    return $dec;
}  
$hash = "FFFFF78001FFFFFF";
$f = bchexdec($hash);
echo $f ."\n";

結果

18446734727894269951

● Message: Call to undefined function bcadd() エラーが出る場合

php-bcmath モジュールが必要です。インストールする必要があります。

https://stackoverflow.com/questions/1273484/large-hex-values-with-php-hexdec

No.1270
07/10 17:34

edit

PHPの三項演算子が苦手な人は ?: の使用から始めることをオススメします

● PHPの三項演算子が苦手な人は次のように記述すると デフォルト値を設定できる と覚えておくことをオススメします

?: の後ろにデフォルト値
$a = @$arg ?: 1;
echo $a; // 「1」と表示される
$arg = 99;
$a = @$arg ?: 1;
echo $a; // 「99」と表示される
$arg = null;
$a = @$arg ?: 1;
echo $a; // 「1」と表示される
$arg = -1;
$a = @$arg ?: 1;
echo $a; // 「-1」と表示される

やっていることは

if ( $arg ){
 // ....
}

なので、

この場合は注意が必要です。

$arg = 0;
$a = @$arg ?: 1;
echo $a; // 「1」と表示される
No.1269
07/10 14:32

edit

PHPでファイルやディレクトリの入ったディレクトリごと削除する

	/**
	 * 中にファイルやディレクトリが入っているディレクトリごと削除する
	 * @param   string      $dir	削除するディレクトリ
	 * @param   boolean     $is_delete_myself	指定したディレクトリ自身を削除するか
	 * @return  string     削除したファイルやリストの結果
	 */
	function remove_directory( $dir, $is_delete_myself=false )
	{
		$result_message = "";
		if ( ! is_dir($dir) ){
			return "ディレクトリ ({$dir}) は存在しません\n";
		}
		else{
			$dir = preg_replace("{/$}","",$dir);
		}

		if ($handle = opendir("$dir")) {
			while (false !== ($item = readdir($handle))) {
				if ($item != "." && $item != "..") {
					if (is_dir("$dir/$item")) {
						$r = remove_directory("$dir/$item", true);
						$result_message .= $r;
					} else {
						unlink("$dir/$item");
						$result_message .= " remove [fie] $dir/$item\n";
					}
				}
			}
			closedir($handle);
			if ( $is_delete_myself == true ){
                rmdir($dir);
                $result_message .= " remove [directory] $dir\n";
            }
		}
		return $result_message;
	}

削除を実行する(指定したディレクトリ自身も削除する)

$r = remove_directory("./my_dir/", true);
echo $r;

結果例

 remove [fie] ./my_dir/b00009vxzx_1.jpg
 remove [fie] ./my_dir/b01lxs5b8x_1.jpg
 remove [fie] ./my_dir/b01lxs5b8x_2.jpg
 remove [fie] ./my_dir/b01lxs5b8x_3.jpg
 remove [directory] ./my_dir

引用元 : https://goo.gl/Z7MFkC

No.1258
06/26 15:43

edit

ファイル

phpの in_array() をisset で代用して高速化する

phpの in_array() を高速化。ではないのですが、安易な in_array をやめて isset を使用すると劇的に早くなります。

● phpの in_array() を使わず isset で代用する

$keys = array(“apples”, “oranges”, “mangoes”, “tomatoes”, “pickles”);
if (in_array(‘mangoes’, $keys)) { … }

$keys = array(“apples” => 1, “oranges” => 1, “mangoes” => 1, “tomatoes” => 1, “pickles” => 1);
if (isset($keys[‘mangoes’])) { … }

引用元 : http://code.xenophy.com/?p=74

No.1214
05/08 11:10

edit

phpで日付の曜日を日本語で表記する

● phpで日付の曜日を日本語で表記する

date_default_timezone_set('Asia/Tokyo');
$week = ['日', '月', '火', '水', '木', '金', '土'];
$dt = new DateTime();
echo $dt->format("Y/m/d"). ' ('. $week[$dt->format('w')] . ') ' . $dt->format("H:i");
echo "\n";

結果例

2018/04/11 (水) 16:02
No.1203
04/11 16:04

edit

Microsoft Edge で history.back() や ブラウザの戻るボタンで戻った時にチェックボックスとラジオボタンが消える

Microsoft Edge で history.back() や ブラウザの戻るボタンで戻った時にチェックボックスとラジオボタンが消える というバグ(仕様っぽい)があります。

これは表示上だけの問題ではなく、DOMツリーからも消えてしまうので、戻ってきた時にJavaScriptで値を見に行っても値自体が存在しません。

以下の方法で対処することは出来ます。(なかなかの力技ですね)

対処法 Microsoft Edgeでブラウザバックをした時ラジオボタンのチェックが外れる問題 - Qiita

ブラウザのhistory.back() Edgeはチェックボックス・ラジオボタンの値が消え、Chromeはhiddenの値が消える | ZEKIOM.NET

No.1188
01/14 17:02

edit

PHPでエクセルファイルを扱う

● PhpSpreadsheetのインストール

composer require phpoffice/phpspreadsheet

● PHPExcelのインストール(古いパッケージ)

現在メンテナンスされていません

composer require phpoffice/phpexcel

● エクセルファイルの読み込みとデータ表示

require_once __DIR__ . '/vendor/autoload.php';

$excel_file  = 'myfile.xlsx';

// ファイルの読み込み
$objPHPExcel = PHPExcel_IOFactory::load( './' . $excel_file );
$objPHPExcel->setActiveSheetIndex(0);	// 先頭のシートを選択
$sheet = $objPHPExcel->getActiveSheet();

foreach ($sheet->getRowIterator() as $row) {
	$tmp = array();
	foreach ($row->getCellIterator() as $cell) {
		$tmp[] = $cell->getValue();
	}
	print_r( $tmp );
}

● データの書き出し

$objPHPExcel = new PHPExcel();
$sheet = $objPHPExcel->getActiveSheet();

for ($i=0; $i <= 10 ; $i++) {
	$sheet->setCellValueByColumnAndRow($i, 3, "テスト{$i}");
}
$writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$writer->save('___test.xlsx');
No.1184
04/10 14:23

edit

パスワードの最後の1文字以外を * にマスクするTwigフィルタ

Twig/Extensionuser/Passwordmask.php を以下のように作成します

class Twig_Extensionuser_Passwordmask extends Twig_Extension
{
    public function getFilters()
    {
        return array('passwordmask' => new Twig_Filter_Method($this, 'passwordmask'));
    }
    public function passwordmask($string)
    {
        if (strlen($string) == 1) {
            return '*';
        }

        $out = '';
        for ($i = 0; $i < strlen($string); $i++) {
            if ($i + 1 == strlen($string)) {$out .= $string[$i];} else { $out .= '*';}
        }
        return $out;
    }
    public function getName()
    {
        return 'passwordmask';
    }
}

使い方

{{ 'aiueo123456' | passwordmask }}

表示結果

**********6
No.1181
12/20 14:40

edit

PHPのpreg_replace_callback() にクラスのメソッドを使用する

PHPのpreg_replace_callback() にクラスのメソッドを使用するには 第2引数に配列で $thisを渡します

$v = preg_replace_callback($pattern, array($this,'my_callback'), $v);
No.1180
12/07 19:40

edit

phpで配列を文字数の多い順にソート(並び替え)する

phpで配列を文字数の多い順にソート(並び替え)するには以下のようにします。

● 普通の配列の場合は usort() を使用します

usort($output_array, create_function('$b,$a', 'return mb_strlen($a, "UTF-8") - mb_strlen($b, "UTF-8");'));

● 連想配列の場合は uasort() を使用します

uasort($output_array, create_function('$b,$a', 'return mb_strlen($a, "UTF-8") - mb_strlen($b, "UTF-8");'));

例:

$my_array = array(
	'あいうえお' ,
	'12345789' ,
	'長い長い文字列のテストです。' ,
);
print_r($my_array);
usort($my_array, create_function('$b,$a', 'return mb_strlen($a, "UTF-8") - mb_strlen($b, "UTF-8");'));
print_r($my_array);

結果 :

Array
(
    [0] => あいうえお
    [1] => 12345789
    [2] => 長い長い文字列のテストです。
)
Array
(
    [0] => 長い長い文字列のテストです。
    [1] => 12345789
    [2] => あいうえお
)

引用元 : https://goo.gl/uhhq1Z

No.1179
12/03 16:12

edit

配列
ソート

IEやEdgeでhistory.back()や「戻る」ボタンで戻った時に消える時の対処法その1

IEやEdgeでhistory.back()や「戻る」ボタンで戻った時に消える時の対処法

PHPでセッションの使用 session_start(); を実行すると、ブラウザのHTTPヘッダには

Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache

というのが必ず送られます。
これが送られるとそのページはキャッシュされないので、例えばフォーム入力画面の場合
次の確認画面から history.back(); で返ってくると、入力欄が消えてしまいます。
(ただし Google Chrome の場合は消えない場合が多いので、必ずIEやEdgeで確認しましょう。)

そこで 次の方法で対処できます。

● 方法1. php ソースに次の3行を記述する

session_start();

// セッション使用時にブラウザキャッシュを有効にする
header('Expires: -1');
header('Cache-Control:');
header('Pragma:');

記述場所は 「session_start() の後」かつ「何か画面に出力する前」です。

● 方法2.

session_cache_limiter('public'); // セッション使用時にキャッシュを使えるようにする
// ↓PHPのデフォルト値は 180 です
session_cache_expire(60); // セッション時のキャッシュ有効時間 60分(1時間)
session_start();

とすると、セッション使用時にもキャッシュ可能になります。

・session_cache_limiterの引数

session_cache_limiterの引数 説明
none no-cacheヘッダを送信しない
nocache no-cacheヘッダを送信する
private キャッシュを利用する(プロキシサーバーにはキャッシュを利用させない)
private_no_expire キャッシュを利用する(プロキシサーバーにはキャッシュを利用させない)
public キャッシュを利用する

ちなみにセッション自体の有効時間は

ini_set("session.cookie_lifetime", 28800); // セッション有効時間 60*60*8(8時間)

として指定します。

No.680
11/25 00:41

edit

Cookie
セッション
エラー対処

Twig で 現在の日付までのドロップダウンリストを生成する

新しい年になった時にドロップダウンリストの項目を一つ増やしたいという時があります。 Twigを使用している場合は次のように書くと現在の年までのドロップダウンリストを生成いたします

<select name="y">
	<option value="">----</option>
{% set year_start = 2010 %}
{% set year_end   = "now"|date("Y") %}
{% for i in year_start..year_end %}
	<option value="{{i}}">{{i}}</option>
{% endfor %}
</select>

↓ このように生成されます

<select name="y">
	<option value="">----</option>
	<option value="2010">2010</option>
	<option value="2011">2011</option>
	<option value="2012">2012</option>
	<option value="2013">2013</option>
	<option value="2014">2014</option>
	<option value="2015">2015</option>
	<option value="2016">2016</option>
	<option value="2017">2017</option>
</select>
No.1174
11/22 17:17

edit

Twig
日付

Twigテンプレートで動的に継承元テンプレートを変更する

Twigテンプレートで動的に継承元テンプレートを変更するには次のように一度変数にファイル名を入れて そこから呼び出します。

lang_settingen の時はファイル「base_english.html」を、それ以外の時はファイル「base_japanese.html」を継承元にするサンプル

{% if lang_setting == 'en' %}{% set base_template = 'base_english.html' %}
{% else %}{% set base_template = 'base_japanese.html' %}
{% endif %}

{% extends base_template %}
No.1171
11/07 15:41

edit

Twig

PHPで日付を比較して日数の差を計算する

「○○○○イベント」まであと xx 日 ! をPHPで算出したい時があります。
以下の様にDatetimeクラスを使うと簡単に算出できます

$event_date = '2017-09-30 15:00:00';
$day1 = new DateTime( $event_date );
$day2 = new DateTime();
$day1->modify('noon');	// 時刻 12:00 をセット
$day2->modify('noon');	// 時刻 12:00 をセット

$interval = $day1->diff($day2);
$interval_day  = (int)$interval->format('%a');

echo "イベントまであと({$interval_day}日)です。";

なおこの diffメソッドは 、日付の「差」を求めるので
例えば「現在の日付」と「2日前の日付」を比較したときの戻り値は「-2」ではなく「2」になります

日付のどちらが古いか新しいかは PHP5.2以降の場合そのままオブジェクトを比較することができます。

if ( $day1 <= $day2 ){
echo( "「当日」または「過ぎています」" );
}


No.1163
09/11 18:09

edit

日付

Twigで日付から日本語の曜日を返すフィルター

Twig/Extensionuser にファイル名 Youbi.php で保存します。

Youbi.php

<?php

class Twig_Extensionuser_Youbi extends \Twig_Extension
{
    public function getFilters()
    {
        return array(
            'youbi' => new \Twig_Filter_Method($this, 'youbi', array(
                'needs_environment' => true,
                'needs_context' => true,
                'is_safe' => array(
                    'evaluate' => true,
                ),
            )),
        );
    }

    public function youbi(\Twig_Environment $environment, $context, $string1)
    {
        $date = new DateTime($string1);
        $w_no = $date->format('w');
        $week = array('日', '月', '火', '水', '木', '金', '土');
        return $week[$w_no];
    }

    protected function parseString(\Twig_Environment $environment, $context, $string)
    {
        $environment->setLoader(new \Twig_Loader_String());
        return $environment->render($string, $context);
    }

    public function getName()
    {
        return 'youbi';
    }
}

● 使い方

{{'2017-08-04' | youbi }}
No.1162
09/08 15:25

edit

日付
Twig

Twigで生年月日から現在の年齢を返すフィルター

new Twig_SimpleFilter('getage', array($this, 'getage')) ,
    /**
     * 誕生日文字列( 例: 1983-12-19)から現在の年齢を返します
     *
     * @param   string      $date_name (例: '1983-12-19')
     * @return  int         現在の年齢
     */
    public function getage( $date_name )
    {
        $birth = date('Ymd', strtotime($date_name));
        $now = date("Ymd");
        return floor(($now-$birth)/10000);
    }

使い方

{{ '1983-12-19' | getage }}歳
No.1159
09/05 16:05

edit

日付
Twig

phpで共通鍵暗号を使った文字列の可逆暗号(暗号化/復号化)を行う(その2)

Packagist を覗いていると「windwalker/crypt」というのがあったので試してみる

● windwalker/crypt のインストール

composer require windwalker/crypt

● windwalker/crypt を使用した暗号化/復号化

crypt_blowfish.php

require_once "vendor/autoload.php";
use Windwalker\Crypt\Cipher\BlowfishCipher;
use Windwalker\Crypt\Crypt;

$crypt = new Crypt(new BlowfishCipher, 'My private key');
$raw       = 'あいうえおかきくけこさしすせそ';
$encrypted = $crypt->encrypt($raw);
$decrypted = $crypt->decrypt($encrypted);

print <<< DOC_END
<table border="1" style="word-break: break-all;">
	<tr><th>raw</th><td>{$raw}</td></tr>
	<tr><th>encrypted</th><td>{$encrypted}</td></tr>
	<tr><th nowrap>decrypted</th><td>{$decrypted}</td></tr>
</table>
DOC_END;

● AES-256-CBC との速度比較

crypt_aes256.php

$method = 'AES-256-CBC';
$iv_length = openssl_cipher_iv_length($method);
$iv = openssl_random_pseudo_bytes($iv_length);
$options = 0;

$raw       = 'あいうえおかきくけこさしすせそ';
$encrypted = openssl_encrypt($raw, $method, $password, $options, $iv);
$decrypted = openssl_decrypt($encrypted, $method, $password, $options, $iv);

print <<< DOC_END
<table border="1" style="word-break: break-all;">
	<tr><th>raw</th><td>{$raw}</td></tr>
	<tr><th>encrypted</th><td>{$encrypted}</td></tr>
	<tr><th nowrap>decrypted</th><td>{$decrypted}</td></tr>
</table>
DOC_END;

● ベンチマーク結果(ab , Requests per second比較。大きいほど早い)

crypt_blowfish.phpcrypt_aes256.php
45.42 [#/sec] (mean)117.17 [#/sec] (mean)
33.58 [#/sec] (mean)105.73 [#/sec] (mean)
40.69 [#/sec] (mean)105.13 [#/sec] (mean)
No.1149
07/14 17:44

edit

PHP Datetime日付のフォーマット

● 例

$dt = new DateTime();
echo $dt->format('Y-m-d H:i:s');
echo $dt->format('Y/m/d (D) H:i:s');

表示例

2017-05-20 07:01:28
2017/05/20 (Sat) 07:01:28

・年

書式 内容
Y 4桁の年。例:2017
y 2桁の年。例:14
L うるう年。1:うるう年 0:うるう年ではない

・月

書式 内容
m ゼロ詰めの月。01~12
n ゼロなしの月。1~12
F フルスペルの月。例:January
M 3文字形式の月。例:Jan
t 月の日数。28~31

・日

書式 内容
d ゼロ詰めの日。01~31
j ゼロなしの日。1~31
z 年間の通算日。0~365

・時

書式 内容
g 12時間単位の時(ゼロなし)。1~12
G 24時間単位の時(ゼロなし)。0~23
h 12時間単位の時。01~12
H 24時間単位の時。00~23

・分

書式 内容
i 分。00~59

・秒

書式 内容
s 秒。00~59

・午前・午後

書式 内容
a 午前:am 午後:pm
A 午前:AM 午後:PM

・曜日

書式 内容
D 3文字形式の曜日。例:Mon
l フルスペルの曜日。例:Monday
N ISO-8601形式の曜日。1(月)~7(日)
W 曜日。0(日)~6(土)

・定数

書式 形式 内容
DATE_ATOM Atom 2015-12-07T14:18:07+09:00
DATE_COOKIE HTTP Cookies Monday, 07-Dec-2015 14:18:07 JST
DATE_ISO8601 ISO-8601 2015-12-07T14:18:07+0900
DATE_RFC822 RFC 822 Mon, 07 Dec 15 14:18:07 +0900
DATE_RFC850 RFC 850 Monday, 07-Dec-15 14:18:07 JST
DATE_RFC1036 RFC 1036 Mon, 07 Dec 15 14:18:07 +0900
DATE_RFC1123 RFC 1123 Mon, 07 Dec 2015 14:18:07 +0900
DATE_RFC2822 RFC 2822 Mon, 07 Dec 2015 14:18:07 +0900
DATE_RFC3339 RFC 3339 2015-12-07T14:18:07+09:00
DATE_RSS RSS Mon, 07 Dec 2015 14:18:07 +0900
DATE_W3C WWW Consortium 2015-12-07T14:18:07+09:00

引用 : https://eng-entrance.com/php-date

No.1143
05/20 16:20

edit

No.1133
10/29 08:54

edit

PEAR run-tests を使ったPHPのユニットテスト

phpでユニットテストを行うときはPHPUnitがお勧めですが, PEARの run-tests( .phpt ) というのもあるので紹介しておきます。

● インストール

PEARがインストールされていれば使えるので PEAR をインストールします。

composer require pear/pear

● テストするコード

例 : m.php

<?php
function implode_recursive($glue, array $pieces) {
    $result = array();
    array_walk_recursive($pieces, function($value) use(&$result) {
        $result[] = $value;
    });
    return implode($glue, $result);
}

● テストファイル( .phpt )の作成

テストファイルをディレクトリ tests/ 以下に作成します。ファイル名は 001.phpt とします。
例 : tests/001.phpt

--TEST--
test 001
--FILE--
<?php
require __DIR__ . '/../m.php';

$test = array(
    "hoge",
    "fuga",
    array(
        array(
            1,
            2,
        ),
        "foo",
        "bar",
        array(),
        "qux",
    ),
    "piyo",
);

var_dump(implode_recursive(",", array()));
var_dump(implode_recursive(",", $test));
var_dump(implode_recursive("",  $test));
?>
--EXPECT--
string(0) ""
string(30) "hoge,fuga,1,2,foo,bar,qux,piyo"
string(23) "hogefuga12foobarquxpiyo"

書き方は次のようになっています

--TEST--
コメント
--FILE--
phpによる標準出力への出力
--EXPECT--
予想される結果

これで「phpによる標準出力への出力」と「予想される結果」を単純に比較してくれます

● テストの実行

コマンドラインから以下のように実行します

cd tests/
pear run-tests

これだけで フォルダ内の全ての .phpt ファイルを読み込んでテストを実行します。

テスト結果

Running 1 tests
PASS test 001[001.phpt]
TOTAL TIME: 00:01
1 PASSED TESTS
0 SKIPPED TESTS

● テスト結果を見やすくする

以下のようにするとテストが失敗した時に色がついて表示されるのでオススメです

pear run-tests | grep --color=auto -i -e 'fail' -e'$'

● エイリアスを作成する

以下のようにエイリアスを作成しておくと phpt と入力するだけでテストが走るので便利です

vi ~/.bash_profile
alias phpt="pear run-tests | grep --color=auto -i -e 'fail' -e'$'"

引用 : http://qiita.com/arai-ta/items/450dd84964ad628e287b

No.1123
08/11 08:49

edit

PEAR
エラー対処

php7で変数の型宣言が厳格なコーディングを行う

php7から変数の型宣言が厳格なコーディングが可能になっていますのでぜひ使いましょう。

● 変数の型を確認する

echo gettype( $val );
var_dump( $val );

● 変数の型指定を厳格にする

declare(strict_types=1);

● 変数の型指定を厳格にしたときのエラー例

<?php
declare(strict_types=1);
function my_func(int $v){
    echo $v."\n";
}
my_func('999');
PHP Fatal error:  Uncaught TypeError: Argument 1 passed to my_func() must be of the type integer, string given, called in /test.php on line 6 and defined in /test.php:3
Stack trace:
#0 /test.php(3): my_func('999')
#1 {main}
  thrown in /test.php on line 7

こちらもあわせて使用すると非常に有効です。
PHPで列挙型(enum)を作る
http://bit.ly/2oTfrz7

No.1122
04/11 15:15

edit

PHP7
エラー対処

phpcs , phpcbf で phpコードを(チェック / 整形)する

多人数が関わるプロジェクトでは phpコードの書式を統一するのが難しくなります。
そこでプログラマー個人にコーディングルールを覚えさせるよりプログラムで自動判別させます。
下記の phpcs がとても便利です。

● squizlabs/PHP_CodeSniffer ( phpcs )

https://github.com/squizlabs/PHP_CodeSniffer/wiki

1. composer コマンドからインストールします

composer global require "squizlabs/php_codesniffer=*"

2. シェルが bash の場合は次のコマンドでパスを追加しておきます

echo 'export PATH=$HOME/.composer/vendor/bin:$PATH' >> .bash_profile
source .bash_profile

● インストールの確認

phpcs --version

● php ソースコードのチェック (phpcs コマンド)

PSR2準拠のソースフォーマットチェックを行います。

phpcs  --report=source  --standard=PSR2  [phpファイル名  または ディレクトリ名 ] 

オプション --standard=PSR2 を付け忘れないようにしましょう。
(オプションをつけないとPEAR準拠のソースフォーマットチェックとなります)

--reportオプションは

--report=source
--report=summary

があります。

● チェックできるコーディングルール一覧を表示する

phpcs -i

The installed coding standards are MySource, PEAR, PHPCS, PSR1, PSR2, Squiz and Zend

● php ソースコードの整形 (phpcbf コマンド)

指定したコーディング規約に沿うようphpソースコードを自動で整形してくれます
例)PSR2準拠に自動整形します

phpcbf  --standard=PSR2  [phpファイル名] 
No.1121
04/11 23:22

edit

エラー対処

PHPMD で PHPソースのチェックを行う

● PHPMDとは?

バグにつながりそうな怪しい ソースコードをチェックして教えてくれる php md。
コーディング時に必ず使うようにしておくとミスやバグが減るので是非使いましょう

● PHPMDのインストール

1. composer コマンドからインストールします

composer global require phpmd/phpmd

2. シェルが bash の場合は次のコマンドでパスを追加しておきます

echo 'export PATH=$HOME/.composer/vendor/bin:$PATH' >> .bash_profile
source .bash_profile

3. phpmd コマンドを入力してパスが通ってるか確認します

phpmd --version

● PHPMDで phpソースコードのチェックを行う

(ソースファイル myfile.php チェックしテキストデータで結果を受け取る。チェックする項目は
codesize,controversial,design,naming,unusedcode)

phpmd  myfile.php  text  codesize,design,naming,unusedcode

オプションの意味

codesize	コードが大きすぎないかチェック
controversial	命名規則など議論の余地がある部分を検出するチェック
design	設計上の関連のチェック
naming	変数名など名前関連のチェック
unusedcode	使われていない変数のチェック
cleancode	綺麗なコードかチェック

書式は以下の通りです

phpmd (phpファイル名) ( text または xml または html ) (オプションをカンマで区切る)

引用 : https://simple-it-life.com/?p=761

● エディタ SublimeTextで PHPMDを使う

次のパッケージをインストールします

SublimeLinter
SublimeLinter-phpmd

・SublimeLinter-phpmdの設定方法

【Package Settings】→【SublimeLinter】→【Settings - User】に記述があります。

設定例: (ルールセットから controversial, design, naming を取り除いています)

    "linters": {
	    "phpmd": {
	        "@disable": false,
	        "args": [],
	        "excludes": [],
	        "delay": 0.75,
	        "rulesets": "cleancode,codesize,unusedcode"
	    }
	}

また反応速度が速いとオートコンプリートと機能がバッティングしてしまうので、SublimeLinterのDelayの値を少し多めにしてやると良いと思います

設定例: ディレイ値を増やす

        "delay": 0.75,

これで PHPファイルを開いているときに自動的にソースのおかしそうなところを指摘してくれます。

合わせて「SublimeLinter-annotations」もインストールしておきましょう

@todo をハイライト表示してくれるのでとても便利です。

● PHPMDにエラー指摘してほしくない項目をソースコードに直接記述する

PHPMDのエラーを回避したい場合は、ソースコードの クラス名またはメソッドの上に PHPDOC 形式で SuppressWarnings を指定することで エラー表示を回避することが出来ます。 指定できる文字列は (PHPMD.XXXXX) という形式で、XXXXXに指定する文字列はこちらのページから調べることが出来ます。

https://phpmd.org/rules/index.html

例)StaticAccessElseExpression 2つのエラーを表示しないようにします

	/**
	 * @SuppressWarnings(PHPMD.StaticAccess)
	 * @SuppressWarnings(PHPMD.ElseExpression)
	 */
	public function hogehoge( $arg )
	{
		// code ...
	}
No.1120
12/11 09:33

edit

エラー対処
composer

phpで共通鍵暗号を使った文字列の可逆暗号(暗号化/復号化)を行う(その1)

● phpで共通鍵暗号を使った(暗号化/復号化)を行う

phpで共通鍵暗号を使った(暗号化/復号化)を行うには, mcrypt , OpenSSL , PEAR::Crypt_Blowfish などがありますが、
mcrypt は近い将来 php 7.2で削除されますし、PEAR::Crypt_Blowfishも古いライブラリーなので OpenSSL から共通鍵暗号を使用します。

※ PHP 7.1.x で推奨されなくなる機能

http://php.net/manual/ja/migration71.deprecated.php

mcrypt 拡張モジュールは十年近くにわたって放置されており、極めて使いづらいものです。 
そこで、この拡張モジュールを非推奨にしました。
かわりに OpenSSL を使いましょう。 mcryptは PHP 7.2 でコアから削除されて、PECL に移る予定です。

● PHPのopenssl_encrypt()を使って AES 256 CBC で暗号化・復号化する例

$data     = 'あいうえおかきくけこさしすせそ';

// 利用可能な暗号メソッド一覧
$ciphers = openssl_get_cipher_methods();
print_r($ciphers);

// 暗号化方式
$method = 'AES-256-CBC';

// IV(初期化ベクトル)に必要な長さを取得
$iv_length = openssl_cipher_iv_length($method);

// IV(初期化ベクトル)をランダム生成
$iv = openssl_random_pseudo_bytes($iv_length);

// OPENSSL_RAW_DATA と OPENSSL_ZERO_PADDING を指定可
$options = 0;

// 暗号化
$encrypted = openssl_encrypt($data, $method, $password, $options, $iv);
echo "暗号文:" .$encrypted . "\n";

// 復号
$decrypted = openssl_decrypt($encrypted, $method, $password, $options, $iv);
echo "平文:" .$decrypted ."\n";

引用 : http://php-archive.net/?p=977

No.1118
07/14 17:42

edit

PHPで日付を扱う(Datetimeまたは DateTimeImmutable )クラス

● PHPで日付を扱うにはDatetime(または DateTimeImmutable )クラスを使用します。

$dt = new DateTime();
echo $dt->format('Y-m-d H:i:s');
echo $dt->format('Y/m/d (D) H:i:s');

戻り値

2017-05-20 07:01:28
2017/05/20 (Sat) 07:01:28

年月日等をバラバラに取り出すときは次のようにします

$dt = new DateTime();
$year = $dt->format('Y'); // 2017
$month = $dt->format('m'); // 04
$day = $dt->format('d'); // 03

● 前の月や次の月など相対的な日付をセットする

$dt->modify('-1 months');	// 1ヶ月 前
$dt->modify('+1 months');	// 1ヶ月 後

$dt->modify('−12 hours');	//12時間 前
$dt->modify('+12 hours');	//12時間 後

$dt->modify('-30 minutes');	//30分 前
$dt->modify('+30 minutes');	//30分 後

$dt->modify('-1 weeks');	//1週間 前
$dt->modify('+1 weeks');	//1週間 後

$dt->modify('first day of this months');	// その月の最初の日
$dt->modify('last day of this months');		// その月の最後の日

$dt->modify('first day of last months');	// 前月の最初の日
$dt->modify('last day of last months');		// 前月の最後の日

$dt->modify('first day of next months');	// 次の月の最初の日
$dt->modify('last day of next months');		// 次の月の最後の日

● php のDatetimeオブジェクトは2種類ある

状況によって使い分けると良いでしょう

● PHP DateTime クラス (ミュータブルなオブジェクト)

http://php.net/manual/ja/class.datetime.php

● PHP DateTimeImmutable クラス (イミュータブルなオブジェクト)

http://php.net/manual/ja/class.datetimeimmutable.php
クラスの説明

このクラスの挙動は DateTime とほぼ同じですが、 自分自身は変更せずに新しいオブジェクトを返すという点だけが異なります。

です

No.1113
04/23 11:28

edit

Smartyで小数点以下を2桁にまとめ、最後がゼロの場合は表示しないようにする

{ assign var="total" value=123.45 }
{ $total | number_format:2 | floatval }
<br>
{ assign var="total" value=123.00 }
{ $total | number_format:2 | floatval }

結果

123.45
123
No.1095
03/03 19:44

edit

Smarty

apacheの mod_rewrite エンコードされたURLに %2Fや%5Cが含まれると404エラーになる場合の回避法

● httpd.confを触れる環境下では httpd.confに以下を追加する

AllowEncodedSlashes On

※ 注意 .htaccessには記述できません。

● PHPやJavaScriptのコーディングで(/)→(%2f)→(%252f)変換することで対応する

・phpでエンコード

// スラッシュだけを変換する
$q = preg_replace("{/}","%2f",$q);
// この後クエリ全体を urldecode します

・phpでデコード

$q = preg_replace("{%252f}","%2f",$q);
No.1094
03/01 13:42

edit

PHPでSafariの「リーダー表示」のように記事を抜き出す

● PHPでSafariの「リーダー表示」のように記事を抜き出す

https://packagist.org/search/?q=Readability

● j0k3r/php-readability

https://packagist.org/packages/j0k3r/php-readability

composer require j0k3r/php-readability
use Readability\Readability;

$url = 'http://www.medialens.org/index.php/alerts/alert-archive/alerts-2013/729-thatcher.html';

// you can use whatever you want to retrieve the html content (Guzzle, Buzz, cURL ...)
$html = file_get_contents($url);

$readability = new Readability($html, $url);
// or without Tidy
// $readability = new Readability($html, $url, 'libxml', false);
$result = $readability->init();

if ($result) {
    // display the title of the page
    echo $readability->getTitle()->textContent;
    // display the *readability* content
    echo $readability->getContent()->textContent;
} else {
    echo 'Looks like we couldn\'t find the content. :(';
}

参考: https://goo.gl/7nz3vK

No.1093
10/31 20:55

edit

composer

ソースコードがPHP7に対応しているかチェックする php7cc

● composerのインストール

ターミナルから次のように入力する

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

インストールは次の A. B. の方法があります。

●A. php7ccのインストール( Composer からインストール)

composer global require sstalle/php7cc

●B. php7ccのインストール( 実行ファイルを直接ダウンロード )

ページ
https://github.com/sstalle/php7cc/releases
にダウンロードリンクがあるので wget コマンドでダウンロードします。

cd ~
wget https://github.com/sstalle/php7cc/releases/download/1.1.0/php7cc.phar
chmod 0755 php7cc.phar

.bash_profile にエイリアスを書いておきます

alias php7cc='~/php7cc.phar'

● php7ccの実行

php7cc 「フォルダ名」

● php7で置き換えなければいけない関数

・mysql関連の関数

mysql 関連の関数は全て mysqli のメソッドに置き換える必要があります。
またその際に mysql への接続情報を渡す必要があります。
例 :

$q = mysql_escape_string( $q );
      ↓
$mysqli = new mysqli('サーバ名', 'ユーザー名','パスワード', 'DB名');
$q      = $mysqli->real_escape_string( $q );

・set_magic_quotes_runtime()

これは削除(コメントアウト可)すればOKです。
例 :

set_magic_quotes_runtime(true);
      ↓
// set_magic_quotes_runtime(true);
No.1091
03/08 11:26

edit

Strict Standards: Only variables should be passed by reference エラーへの対応

PHP5.6以降では配列関係の参照渡しの関数にデータを渡す時は一度変数に入れる必要があります。

● エラーとなる例

$new_array = end( array_keys($array) );

● このように変更します

$ar_key = array_keys($array);
$new_array = end( $ar_key );
No.1089
02/08 18:30

edit

配列
エラー対処

PHPのcomposer使い方とautoloaderの高速化

● composerのインストール

ターミナルから次のように入力する

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

● composerのバージョンの確認

composer -v

● composerを使ってPHPパッケージをインストールする

composer require 『パッケージ名』

● composerを使ってPHPパッケージをバージョン指定してインストールする

(例 バージョン 1.5.4 をインストールする場合)

composer require 『パッケージ名:1.5.4』

● composerを使ってPHPパッケージをアンインストールする

composer remove --update-with-dependencies 『パッケージ名』

● codeigniterで autoload を使用する

ファイル application/config/config.php に設定があるので以下のように変更します

$config['composer_autoload'] = TRUE;

● composer の autoloader を高速化する

composer.json があるディレクトリから下記のコマンドを実行

composer --optimize-autoloader update

ファイル vendor/composer/autoload_classmap.php の中身がフルパスを記述したものに書き換わりファイルを探しに行く時間が短縮されるので高速になります。

● composer を使ってインストールしたモジュールのバージョンを表示する

composer.json があるディレクトリから実行します

composer show

● composer を使ってインストールしたモジュールのバージョンを最新にする

composer.json があるディレクトリから実行します

composer update

● composer 本体のバージョンアップ(update)

composer自身(自体)をアップデートします。

composer self-update
No.1086
10/19 18:01

edit

composer

Twigのバージョンを表示する

Twigのバージョンを表示するには

<p>twigのバージョンは : {{ constant('Twig_Environment::VERSION') }}</p>

とします。

なお Twigのバージョン2 を利用するには PHP7以上が必要です。

No.1079
01/20 17:19

edit

Twig

PHPの true / false を目に見える形で表示する。

true / false 値をデバッグする時に目に見える形で表示したい時があります。
そんなときは `var_export()` を使って

var $my_flag = true;
print ( var_export( my_flag ) );

とします。

No.1066
12/16 15:13

edit

ApacheのPHP実行ユーザー名を確認する

ApacheのPHP実行ユーザー名を確認する

1. ApacheのPHP実行ユーザー名を確認するには phpinfo() の次の項目を確認します。

2. PHPプログラム内からApacheのPHP実行ユーザー名を確認するには以下のコードを記述します。

print "<pre>";
$d = posix_getpwuid(posix_geteuid());
print_r($d);
print "</pre>";

Array
(
    [name] => apache
    [passwd] => x
    [uid] => 48
    [gid] => 48
    [gecos] => Apache
    [dir] => /var/www
    [shell] => /sbin/nologin
)

ApacheのPHP実行ユーザーを変更する

ApacheのPHP実行ユーザーは `/etc/httpd/conf/httpd.conf` に記述してあります

User apache
Group apache

これを変更して apache を再起動すれば変更されます

添付ファイル1
No.1065
02/03 17:28

edit

添付ファイル

Apache

PHPでXpathでスクレイピングできるモジュール

● PHPでXpathでスクレイピングできるモジュール

● php-spide でスクレイピング

composer require vdb/php-spider
<?php

use VDB\Spider\Spider;
use VDB\Spider\Discoverer\XPathExpressionDiscoverer;
use VDB\Spider\StatsHandler;

require_once "./vendor/autoload.php";
$spider = new Spider('https://google.co.jp/');
// $spider->getDiscovererSet()->set(new XPathExpressionDiscoverer("//div"));
$spider->getDiscovererSet()->maxDepth = 3;
$spider->getQueueManager()->maxQueueSize = 10;
// $statsHandler = new StatsHandler();
// $spider->getQueueManager()->getDispatcher()->addSubscriber($statsHandler);
// $spider->getDispatcher()->addSubscriber($statsHandler);
$spider->crawl();
foreach ($spider->getDownloader()->getPersistenceHandler() as $resource) {
    echo "\n" . $resource->getCrawler()->filterXpath('//div')->text() ."\n";
}

● querypath をインストールしWEBサイトのタイトルとdescriptionを取得する

・1. querypath をインストール

インストールするディレクトリ(CodeIgniterの場合は /codeigniter/application/)に移動しターミナルから

composer require querypath/querypath

でインストール。

・2. querypath を読み込み

CodeIgniterを使用している場合は config/config.php

$config['composer_autoload'] = TRUE;

で自動的に読み込まれます。

Laravel を使用している場合は何もしなくても自動的に読み込まれます。

フレームワークを使用していない場合は

require_once "vendor/autoload.php";

・3. querypath でWEBページの情報を取得する(例:YahooトップページのタイトルとDescriptionを表示します)

require_once "vendor/autoload.php";
$url = 'http://yahoo.co.jp/';
$html = file_get_contents($url);
$qp = html5qp($html);
print qp($html, 'title')->text();
print qp($html, 'meta[name=description]')->attr("content");
No.1055
01/23 12:22

edit

Xpath
CodeIgniter

PHPが「ブラウザから起動されたか?」「コマンドラインから起動されたか?」を判別する is_cli()

PHPが「ブラウザから起動されたか?」「コマンドラインから起動されたか?」を判別するには以下のようにします。

function is_cli()
{
    if (php_sapi_name() === 'cli' || defined('STDIN')) {
        return true;
    }
    return false;
}
if ( is_cli() === true ){
    echo 'コマンドライン(CLI)からの起動です。';
}
No.1053
05/23 10:16

edit

PHPで受信したHTMLメールやマルチパートメールを解析する

PHPで受信したHTMLメールを解析するには php-mime-mail-parser を使用すると便利です
https://packagist.org/packages/php-mime-mail-parser/php-mime-mail-parser

● 1. php-mime-mail-parser をインストール

a. composer.json からインストール

composer.json を以下のようにセット

{
    "require": {
        "php-mime-mail-parser/php-mime-mail-parser": "^2.4"
    }
}

b. composerコマンドからインストール

composer  require php-mime-mail-parser/php-mime-mail-parser

● 2. php-mime-mail-parser で受信したHTMLメールを解析する

require_once __DIR__ . '/../vendor/autoload.php';
$Parser = new PhpMimeMailParser\Parser();
$mail_src = file_get_contents('mail.txt');
$Parser->setText($mail_src);
$to            = $Parser->getHeader('to'); // "test" <test@example.com>, "test2" <test2@example.com>
$addressesTo   = $Parser->getAddresses('to'); //Return an array : [[test, test@example.com, false],[test2, test2@example.com, false]]
$from          = $Parser->getHeader('from'); // "test" <test@example.com>
$addressesFrom = $Parser->getAddresses('from'); //Return an array : test, test@example.com, false
$subject       = $Parser->getHeader('subject');
$text          = $Parser->getMessageBody('text');
$html          = $Parser->getMessageBody('html');
print_r($html);

● 3. もしPHPのpecl拡張 mailparse がサーバにない時はインストールする

1. phpize をインストール(もしなければ)

yum -y install php-devel

2. mailparse をコンパイル

wget https://pecl.php.net/get/mailparse-2.1.6.tgz
tar zxvf mailparse-2.1.6.tgz
cd mailparse-2.1.6
phpize
 ./configure
make
make install

make install まで無事終了すると次のような表示が出ます。

Installing shared extensions:     /usr/lib64/php/modules/



No.1048
04/10 13:46

edit

メール

phpでx日経過した古いファイルやディレクトリを削除する

テンポラリファイルなど、何日か前のファイルを削除したい時があると思います。

●PHPでファイル、ディレクトリ一覧を取得する

例:my_folder 以下のファイル、ディレクトリ一覧を取得します。

$dir = dirname(__FILE__) . '/my_folder/';  
$list = get_file_dir_list($dir);  
// get_file_dir_list
function get_file_dir_list($dir=''){
  if ( !$dir || !is_dir($dir) ){ die('dirを正しく設定してください。');}
  $iterator = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator(
      $dir,
      FilesystemIterator::SKIP_DOTS
      |FilesystemIterator::KEY_AS_PATHNAME
      |FilesystemIterator::CURRENT_AS_FILEINFO
    ), RecursiveIteratorIterator::CHILD_FIRST
  );
  $list = array();
  foreach($iterator as $pathname => $info){
    $list[] = $pathname;
  }
  return $list;
}

●X日経過したファイル、ディレクトリを削除する

例:my_folder 以下のファイル、ディレクトリから1ヶ月以上前のものは削除します。

$list = get_file_dir_list($dir);  
print_r($list);  
del_file_dir($list, '-1 month');  
// del_file_dir
function del_file_dir( $list=array(), $expire_date_str='-1 month' ){
  //削除期限
  date_default_timezone_set('Asia/Tokyo');
  $expire_timestamp = 0;
  if (($expire_timestamp = strtotime($expire_date_str)) === false) { die("The expire string : ({$expire_date_str}) is bogus"); }

  foreach ($list as $file_path) {
   if ( preg_match("/\.gitkeep/", $file_path) ){ continue; } // .gitkeep は削除しない
    $mod = filemtime( $file_path );
    if($mod < $expire_timestamp){
      if (is_dir($file_path)){
        echo 'ディレクトリ削除します : '. $file_path.date("Y-m-d H:i:s", $mod)."\n";
        rmdir($file_path) or die("can not delete directory:({$file_path})");
      }
      if (is_file($file_path)){
        echo 'ファイル削除します : '. $file_path.date("Y-m-d H:i:s", $mod)."\n";
        unlink($file_path) or die("can not delete file:({$file_path})");
      }
    }
  }
}
No.1022
12/08 16:48

edit

PHPで配列の重複した値を取り除く

● 重複した値を持つ配列を重複値を綺麗に取り除く

AAA
BBB
DDD
DDD
FFF

 ↓

AAA
BBB
DDD
FFF

PHPコードは

$my_ar = array(
  'AAA' ,
  'BBB' ,
  'DDD' ,
  'DDD' ,
  'FFF' ,
);
print_r($my_ar);
$my_ar = array_merge(array_unique($my_ar));
print_r($my_ar);

です。

● 配列に重複があるかどうかチェックする 関数

重複がある時に true を返します

function array_same_values($array) {
    return array_unique($array) !== $array;
}

です。 引用 : http://bit.ly/1MRi1fr

No.1021
04/06 13:59

edit

配列

PHP5.6 iconv_set_encoding Deprecated エラーの対処

PHP5.6以上では

iconv_set_encoding('output_encoding', 'UTF-8');

は下記のようなエラーとなります

Deprecated: iconv_set_encoding(): Use of iconv.internal_encoding is deprecated in xxxxx.php on line 99

● 対処方法

とりあえずエラーを消したい場合は以下のように一括で置換するといいでしょう

iconv_set_encoding('output_encoding', 'UTF-8');

   ↓

if ( (float)phpversion() < 5.6 ){ iconv_set_encoding('output_encoding', 'UTF-8'); }
No.1013
09/16 18:23

edit

エラー対処

PHPでCSVを読み込み、出力(ダウンロード)させるLeague CSV

◆ 素のPHPのみでCSV読み込みをする

$file_path = 'data_100.csv';
$file = new SplFileObject($file_path);
$file->setFlags(SplFileObject::READ_CSV);
$convert_count = 0;
foreach ($file as $line) {
	print_r($line);
}

PHPだけでCSV読み込みは可能ですが、工夫しないと改行のみの行も出力されます。

◆ league/csvを使用してCSVファイルを扱う (要PHP7以上)

https://packagist.org/packages/league/csv

● 1. インストール

composerを使用します

composer require league/csv

● 2. CSVの読み込み

composerを使用しているので autoload.php を読み込みます

$php_version = (float)phpversion();
if ( $php_version < 7.0 ){ die("league/csv を使用するにはPHP バージョン7.0以上が必要です");}
require './vendor/autoload.php';
use League\Csv\Reader;

// CSVファイルの読み込み
$csv = Reader::createFromPath("./language.csv");

// ヘッダ(先頭行)を取得
$headers = $csv->fetchOne();
var_dump($headers);

// CSVデータを読み込んで出力
$records = $csv->getRecords();
foreach ($records as $offset => $record) {
    print_r($offset);
    print_r($record);
}

● 2. CSVの出力

$php_version = (float)phpversion();
if ( $php_version < 5.5 ){ die("league/csv を使用するにはPHP バージョン5.5以上が必要です");}
require APPPATH.'/vendor/autoload.php';
use League\Csv\Writer;

// ファイルの出力
$csv_writer = Writer::createFromFileObject(new SplTempFileObject());
$csv_writer->insertOne( array('カラム1','カラム2','カラム3' ) );
$csv_writer->output('users.csv');

● league/csvのマニュアル

http://csv.thephpleague.com/9.0/

No.1012
01/17 18:45

edit

composer
CSV

PHPでFTPファイルアップロード / ダウンロード を行う【flysystem】

PHPでFTPファイルアップロード / ダウンロード を行うには PHPのFTP関数 http://php.net/ftp を使用する方法がありますが、

■ flysystem

https://packagist.org/packages/league/flysystem

を使用するほうが早く、FTPをはじめとする次の転送方式にも同じインターフェイスで対応できます(要 追加インストール)

  • local
  • Amazon Web Services - S3 V2 / V3
  • Rackspace Cloud Files
  • Dropbox
  • OneDrive
  • Copy
  • ftp
  • Sftp
  • Zip
  • WebDAV
  • PHPCR
  • Azure Blob Storage
  • NullAdapter
  • Redis
  • Fallback
  • Memory
  • Google Cloud Storage
  • SinaAppEngine Storage

1. インストール

composer からインストールします

composer require league/flysystem

2. 読み込み(autoload.php)

autoload.php を読みこませればOK

autoloadを使いたくない場合は次のように spl_autoload_register() に無名関数を登録してオートロードを作成します。

spl_autoload_register(function($class) {
    $prefix = 'League\\Flysystem\\';
    if ( ! substr($class, 0, 17) === $prefix) {
        return;
    }
    $class = substr($class, strlen($prefix));
    $location = __DIR__ . 'path/to/flysystem/src/' . str_replace('\\', '/', $class) . '.php';
    if (is_file($location)) {
        require_once($location);
    }
});

3.ファイルシステムへの接続

(ローカル)

use League\Flysystem\Filesystem;
use League\Flysystem\Adapter\Local as Adapter;
$filesystem = new Filesystem(new Adapter('/path/to/directory'));

(FTP)

use League\Flysystem\Adapter\Sftp as Adapter;
$filesystem = new Filesystem(new Adapter(array(
    'host' => 'example.com',
    'port' => 21,
    'username' => 'username',
    'password' => 'password',
    'privateKey' => 'path/to/or/contents/of/privatekey',
    'root' => '/path/to/root',
    'timeout' => 10,
)));

4. ファイルの操作

// ファイルの存在確認
$exists = $filesystem->has('path/to/file.txt');
// ファイルを読み込む
$contents = $filesystem->read('path/to/file.txt');
// ファイルを読み込むストリームを得る
$stream = $filesystem->readStream('something/is/here.ext');
// ファイルに書き込む
$filesystem->write('path/to/file.txt', 'contents');
// ファイルに追記する
$filesystem->put('path/to/file.txt', 'contents');
// ファイルを削除する
$filesystem->delete('path/to/file.txt');
// ファイルを読み込んで削除する
$contents = $filesystem->readAndDelete('path/to/file.txt');
// ファイルをリネーム(移動)する
$filesystem->rename('filename.txt', 'newname.txt');

5. ftp_connect() 関数がありませんエラーが出る場合

Fatal error: Call to undefined function League\Flysystem\Adapter\ftp_connect() in vendor/league/flysystem/src/Adapter/Ftp.php on line 98

この場合はPHPのftp関数が使用できないサーバですので使用できません。 ソケット通信を使用したFTPクラスを使用するといいでしょう

https://gist.github.com/kobapan/97dcf3039366be1f326d

No.1009
03/04 11:57

edit

ファイル

PHPでファイルを開いて1行ずつ読み込み、新規ファイルへデータを書き出し

● PHPでファイルを開いて1行ずつ読み込み( SplFileObject )

$file = new SplFileObject(__DIR__ . '/input.html', 'r');
$file->setFlags(SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE);

foreach ($file as $n => $line) {
    if ($line === false) {
        continue;
    }
    echo "$n $line", PHP_EOL;
}

● PHPでファイルを開いて1行ずつ読み込み

$filename = 'input.txt';
$fp = fopen($filename,'r') or die("ファイル({$filename})のオープンに失敗しました");
while ( ($line = fgets($fp,99999)) !== false ) { // 1行あたり最大99999bytes
	print "$line\n";
}
fclose($fp);

● PHPで新規ファイルへの書き込み

$filename = 'output.txt';
$data = 'テストデータです';
$tmp_filename = getmypid().'.tmp';
$fp = fopen($tmp_filename, 'w');
fwrite($fp, $data);
fclose( $fp );
@mkdir(dirname($filename), 0755, true); // ディレクトリ がなければ自動で作成
rename($tmp_filename, $filename);
No.544
09/06 16:38

edit

ファイル

PHP5.6での【Deprecated: Non-static method】エラーの対応

PHP5.6ではstaticではないメソッドを直接呼び出すとエラーが出ます。

■ 例:PHP5.6では以下のコードはエラーとなる

$config = Spyc::YAMLLoad($yml_filename);

■ 対処法: 以下のようにコードを変更します。

$spyc = new Spyc();
$config = $spyc->YAMLLoad($yml_filename);

参考 : http://bit.ly/1PAKIIC

No.996
01/18 14:45

edit

エラー対処

phpのimagemagickで画像を正方形に切り抜く

画像のサムネイルを作成したい場合にphpで自動でできると便利です。 そこでimagemagickを使用します。

ディレクトリ【data】の中に入っている画像【my.jpg】を写真中央で正方形に切り抜き【th_my.jpg】で保存する

$data_dir = 'data';
$input_image  = "my.jpg";
$output_image = "th_".$input_image;

$image = file_get_contents("{$data_dir}/$input_image");
$im = new Imagick();
$im->pingImageBlob($image);
$org_width  = $im->getImageWidth();
$org_height = $im->getImageHeight();
echo 'original image size : ' . $org_width . ' x ' . $org_height ."<br>\n";

$size = $org_width;
if ( $org_width > $org_height){ $size = $org_height; }

$width  = $size;
$height = $size;
$im->readImage("{$data_dir}/$input_image");
$im->cropThumbnailImage($width, $height);
$im->writeImage("{$data_dir}/$output_image");
echo "thumbnail created : {$data_dir}/$output_image";
No.994
01/08 15:55

edit

画像

PHPでスペース区切りの文字列で検索文字をANDマッチする

いわゆるGoogleなどの検索エンジンのようにスペース区切りをANDマッチする方法

function list_and_match($data, $search_str_space_separated){
	$search_str_space_separated = mb_convert_kana($search_str_space_separated, "s");
	$search_list = array();
	$search_list = preg_split("/\s/",$search_str_space_separated);
	$flag = 1;
	foreach ($search_list as $v) {
		if ( ! preg_match("/{$v}/iu",$data) ){
			$flag = false;
			break;
		}
	}
	return $flag;
}
$text = "長い長い日本語のテストを行います。";
$search_text = "長い テスト";
if ( list_and_match($text, $search_text) ){
 echo 'マッチしました';
}
No.983
12/08 20:14

edit

日本語

PHPでPCの機種依存文字を検出し、変換(削除)する。

PHPでPCの機種依存文字を検出し、変換(削除)するには以下のようにします。

function replace_kishu_kanji( $subject='' ){
  $search  = array( '①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩', '⑪', '⑫', '⑬', '⑭', '⑮', '⑯', '⑰', '⑱', '⑲', '⑳', 'Ⅰ', 'Ⅱ', 'Ⅲ', 'Ⅳ', 'Ⅴ', 'Ⅵ', 'Ⅶ', 'Ⅷ', 'Ⅸ', 'Ⅹ', '㍉', '㌔', '㌢', '㍍', '㌘', '㌧', '㌃', '㌶', '㍑', '㍗', '㌍', '㌦', '㌣', '㌫', '㍊', '㌻', '㎜', '㎝', '㎞', '㎎', '㎏', '㏄', '㎡', '㍻', '〝', '〟', '№', '㏍', '℡', '㊤', '㊥', '㊦', '㊧', '㊨', '㈱', '㈲', '㈹', '㍾', '㍽', '㍼', '∮', '∑', '∟', '⊿', '纊', '褜', '鍈', '銈', '蓜', '俉', '炻', '昱', '棈', '鋹', '曻', '彅', '丨', '仡', '仼', '伀', '伃', '伹', '佖', '侒', '侊', '侚', '侔', '俍', '偀', '倢', '俿', '倞', '偆', '偰', '偂', '傔', '僴', '僘', '兊', '兤', '冝', '冾', '凬', '刕', '劜', '劦', '勀', '勛', '匀', '匇', '匤', '卲', '厓', '厲', '叝', '﨎', '咜', '咊', '咩', '哿', '喆', '坙', '坥', '垬', '埈', '埇', '﨏', '塚', '增', '墲', '夋', '奓', '奛', '奝', '奣', '妤', '妺', '孖', '寀', '甯', '寘', '寬', '尞', '岦', '岺', '峵', '崧', '嵓', '﨑', '嵂', '嵭', '嶸', '嶹', '巐', '弡', '弴', '彧', '德', '忞', '恝', '悅', '悊', '惞', '惕', '愠', '惲', '愑', '愷', '愰', '憘', '戓', '抦', '揵', '摠', '撝', '擎', '敎', '昀', '昕', '昻', '昉', '昮', '昞', '昤', '晥', '晗', '晙', '晴', '晳', '暙', '暠', '暲', '暿', '曺', '朎', '朗', '杦', '枻', '桒', '柀', '栁', '桄', '棏', '﨓', '楨', '﨔', '榘', '槢', '樰', '橫', '橆', '橳', '橾', '櫢', '櫤', '毖', '氿', '汜', '沆', '汯', '泚', '洄', '涇', '浯', '涖', '涬', '淏', '淸', '淲', '淼', '渹', '湜', '渧', '渼', '溿', '澈', '澵', '濵', '瀅', '瀇', '瀨', '炅', '炫', '焏', '焄', '煜', '煆', '煇', '凞', '燁', '燾', '犱', '犾', '猤', '猪', '獷', '玽', '珉', '珖', '珣', '珒', '琇', '珵', '琦', '琪', '琩', '琮', '瑢', '璉', '璟', '甁', '畯', '皂', '皜', '皞', '皛', '皦', '益', '睆', '劯', '砡', '硎', '硤', '硺', '礰', '礼', '神', '祥', '禔', '福', '禛', '竑', '竧', '靖', '竫', '箞', '精', '絈', '絜', '綷', '綠', '緖', '繒', '罇', '羡', '羽', '茁', '荢', '荿', '菇', '菶', '葈', '蒴', '蕓', '蕙', '蕫', '﨟', '薰', '蘒', '﨡', '蠇', '裵', '訒', '訷', '詹', '誧', '誾', '諟', '諸', '諶', '譓', '譿', '賰', '賴', '贒', '赶', '﨣', '軏', '﨤', '逸', '遧', '郞', '都', '鄕', '鄧', '釚', '釗', '釞', '釭', '釮', '釤', '釥', '鈆', '鈐', '鈊', '鈺', '鉀', '鈼', '鉎', '鉙', '鉑', '鈹', '鉧', '銧', '鉷', '鉸', '鋧', '鋗', '鋙', '鋐', '﨧', '鋕', '鋠', '鋓', '錥', '錡', '鋻', '﨨', '錞', '鋿', '錝', '錂', '鍰', '鍗', '鎤', '鏆', '鏞', '鏸', '鐱', '鑅', '鑈', '閒', '隆', '﨩', '隝', '隯', '霳', '霻', '靃', '靍', '靏', '靑', '靕', '顗', '顥', '飯', '飼', '餧', '館', '馞', '驎', '髙', '髜', '魵', '魲', '鮏', '鮱', '鮻', '鰀', '鵰', '鵫', '鶴', '鸙', '黑', 'ⅰ', 'ⅱ', 'ⅲ', 'ⅳ', 'ⅴ', 'ⅵ', 'ⅶ', 'ⅷ', 'ⅸ', 'ⅹ', '¦', ''', '"' );
  $replace = array('(1)','(2)','(3)','(4)','(5)','(6)','(7)','(8)','(9)','(10)','(11)','(12)','(13)','(14)','(15)','(16)','(17)','(18)','(19)','(20)','I','II','III','IV','V','VI','VII','VIII','IX','X','ミリ','キロ','センチ','メートル','グラム','トン','アール','ヘクタール','リットル','ワット','カロリー','ドル','セント','パーセント','ミリバール','ページ','mm','cm','km','mg','kg','cc','m2','平成' );
  $result = str_replace($search, $replace, $subject);
  return $result;
}
$test = '①テスト2㍉3日本語のテストです';
$result = replace_kishu_kanji($test);
echo $test;
No.978
11/19 11:18

edit

日本語

PHPでURLの存在を確認する

PHPでURLの存在を確認するには以下のようにします。

$url = 'http://XXX.XXX.XXXXXX';
if($fp = @fopen($url, 'r')){
  fclose($fp);
  echo '存在します';
}
else{
  echo '存在しません';
}
No.977
10/14 11:22

edit

PHPから日本語フォントを使ってPDFを生成出力する【TCPDF】

PHPから動的にPDFを生成し出力やプリントするには古くは【FPDF】を使用しましたが、現在では【TCPDF】を使用します。 TCPDFを利用するメリットは以下のとおり

・文字コード「UTF-8」が使用できる
・TTFフォントを変換しなくても使用できる(自動変換が行われる)

1. TCPDFのダウンロードと設置

http://sourceforge.net/projects/tcpdf/files/ からダウンロードしてフォルダごとサーバにアップロード

2. フォント(.ttf)のアップロード

【tcpdf/fonts】の中に【ttf】フォルダを作ってそこにフォントファイルをアップロードします。

3. TCPDFを使ったPHPからのPDF出力

デフォルトで入っている「Helvetica」と自分でアップロードした「IPAゴシック」を使ってPDF出力する例
「IPAゴシック」のフォントファイルは http://ipafont.ipa.go.jp/old/ipafont/download.html からダウンロードし ( ./tcpdf/fonts/ttf/ipaexg.ttf )に置いておきます

require_once('tcpdf/tcpdf.php');
$pdf = new TCPDF("L", "mm", "A4", true, "UTF-8" );
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->AddPage();
$font = new TCPDF_FONTS();
// フォント:helvetica
$font_0 = $font->addTTFfont( 'フォントファイルまでのフルパス/helvetica.php');
$pdf->SetFont($font_0 , '', 32,'',true);
$pdf->Text(0, 0, "alphabetica ABCDEFG" );
// フォント:IPAゴシック
$font_1 = $font->addTTFfont('フォントファイルまでのフルパス/ipaexg.ttf');
$pdf->SetFont($font_1 , '', 32,'',true);
$pdf->Text(0, 15, "美しい日本語のフォントを表示" );
$pdf->Output("cd_cover_template.pdf", "I");

● 4. PHPでTCPDFを使ってHTMLをPDF化する

https://qiita.com/noratmt/items/d0bc4bc95eaf92d07ca6

No.967
12/13 11:54

edit

pdf
日本語
画像

PHP 5.4のE_STRICTエラーに対応する

PHP 5.4からは 5.3までは出力されなかった【E_STRICTエラー】がデフォルトで出力されるようになっています。 なのでPHPのバージョンを 5.3以下から5.4以上に上げるとE_STRICTエラーが表示されることがよくあります。

1. PHP 5.4のE_STRICTエラーの対処法(ソースを修正する)

自分で書いたソースの場合はエラーの内容を調べて修正するのが一番よいでしょう。
http://goo.gl/moKrOg

2. PHP 5.4のE_STRICTエラーの対処法(エラーを表示しないようにする)

そもそもPHPのバージョンが5.3以下の場合は出力されてなかったエラーなので、そもそもエラーを表示させないという手法。 古いPEARパッケージにはこのエラーが含まれていることが多いので以下のようにエラーが出る箇所を【エラー設定】【エラー戻し】で囲むといいでしょう。

// 【エラー設定】E_STRICT , E_DEPRECATED を非表示
$old_error = error_reporting( E_ALL & ~E_STRICT & ~E_DEPRECATED);

	// PEARパッケージの処理(例)
	require_once 'XML/Unserializer.php'; // 例:PEARの XML::Unserializer は確実にE_STRICTエラーが出ます。
	// 何かしらの処理

// 【エラー戻し】
error_reporting($old_error);
No.966
07/30 22:40

edit

PEAR
XML
エラー対処

Twigテンプレートの変数の中で変数をevalするフィルタ

Twigテンプレートの変数の中で変数をevalするフィルタがとても便利なので紹介します。

Twig > Extension > Evalute.php で保存

<?php
class Twig_Extension_Evaluate extends \Twig_Extension {
    public function getFilters( ) {
        return array(
            'evaluate' => new \Twig_Filter_Method( $this, 'evaluate', array(
                'needs_environment' => true,
                'needs_context' => true,
                'is_safe' => array(
                    'evaluate' => true
                )
            ))
        );
    }
    public function evaluate( \Twig_Environment $environment, $context, $string ) {
        $loader = $environment->getLoader( );
        $parsed = $this->parseString( $environment, $context, $string );
        $environment->setLoader( $loader );
        return $parsed;
    }
    protected function parseString( \Twig_Environment $environment, $context, $string ) {
        $environment->setLoader( new \Twig_Loader_String( ) );
        return $environment->render( $string, $context );
    }
    public function getName( ) {
        return 'evaluate';
    }
}

Twig読み込み時に以下の行を追加

$twig->addExtension( new Twig_Extension_Evaluate() );

以下のように変数の中の変数が展開できます

{% set var = 'inner variable' %}
{{'this is a string with an {{var}}'|evaluate}}

 ↓

this is a string with an inner variable

このような書き方もできます(ハッシュのメンバ名が変数の時に展開する)

$data['column_name'] = "data_id";
$data['data_hash']['data_id'] = 999;
{{data_hash[column_name]|evaluate}}

 ↓

999

引用 : http://goo.gl/Y1LlSz

No.959
11/29 23:08

edit

Twig

テンプレートエンジンTwigに自作フィルタを追加する

Twigに自作フィルタを追加するにはフィルタを定義して addFilter するだけでOKです。

例 : ファイルの存在をチェックする file_exists フィルタを追加する(PHPファイル内に以下を追加)

$filter = new Twig_SimpleFilter('file_exists', function ($filename) {
	// ディレクトリは適宜書き換えること
	return file_exists(dirname(__FILE__)."/{$filename}");
});
$twig->addFilter($filter);

使い方(HTML内で以下のように記述)

{% if "test.jpg"|file_exists  %}
	ファイルが存在します
{% else %}
	ファイルは存在しません
{% endif %}
No.955
07/02 14:18

edit

Twig
ファイル

テンプレートエンジン『Twig』と『Smarty』『Laravel Blade』比較表

● テンプレートの読み込みとディレクトリのセット(PHPファイルに記述)

※ Smarty

require_once('Smarty/Smarty.class.php');
$smarty = new Smarty();
$smarty->template_dir = './templates/';
$smarty->compile_dir = './templates_c/';

※ Twig

require_once('Twig/Autoloader.php');
Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem("./templates/");
$twig = new Twig_Environment($loader, array(
	'cache' => 'cache_twig',
	 'debug' => false ,
));

● 変数のアサイン(PHPファイルに記述)

※ Smarty

$smarty->assign( array("mydata" => $hoge) );

※ Twig

$twig->addGlobal( "mydata", $hoge );

● 変数のアサイン(テンプレートファイルに記述)

※ Smarty

{assign var="aaa" value="999" }

※ Twig

{% set aaa = '999' %}

※ Twig(ヒアドキュメント的)

{% set aaa %}
    <div id="pagination">
        ...
    </div>
{% endset %}

※ Laravel Blade

@php($aaa = 999)

または

@php $aaa = 999; @endphp

または

@php
$aaa = 999;
@endphp

● テンプレートの表示(PHPファイルに記述)

※ Smarty

$template_file = 'myfile.html';
$smarty->display( $template_file );

※ Twig

$hash = array(
'id' => 999 ,
'name' => 'hoge' ,
);
$template_file = 'myfile.html'
echo $twig->render($template_file, $hash);

● テンプレートの継承(レイアウトテンプレートに記述)

※ Twig

{% block content %}
{% endblock %}

※ Laravel Blade

@yield('content')

● テンプレートの継承(子テンプレートに記述)

※ Twig

{% extends "layout" %}

{% block content %}
{% endblock %}

※ Laravel Blade

@extends('layout')
@extends('layout.blade.php') // ファイル名で記述してもok

@section('content')
@endsection

● ループ処理(for 文)(HTMLファイル内に記述)

※ Smarty

{section name=i start=0 loop=10}
  {$smarty.section.i.index}回目
{/section}

※ Twig

{% for i in 0..10 %}
  {{ i }}回目
{% endfor %}

※ Laravel Blade

@for ($i = 0; $i < 10; $i++)
    {{ $i }}回目
@endfor

● ループ処理(foreach 文)とループ回数(HTMLファイル内に記述)

※ Smarty

{ foreach from=$my_loop key="k" item="v" }
{$v.user_name}
{ /foreach }

※ Twig

{% for k,v in my_loop %}
  <h1>{{ loop.index }}番目</h1>
  {% if loop.first %}最初の要素です。
  {% elseif loop.last %}最後の要素です。
  {% else %}{{ v.user_name }}
  {% endif %}   
{% endfor %}

Twig の loop.index1 から始まります。

※ Laravel Blade ( foreach )

@foreach ($users as $user)
    {{$loop->index}}

    @if ($loop->first)
        これは最初の要素です
    @endif

    @if ($loop->last)
        これは最後の要素です
    @endif

    <p>これは {{ $user->id }} ユーザーです。</p>
@endforeach

Laravel Blade の $loop->index0 から始まります。

※ Laravel Blade ( forelse )おすすめ

@empty が使用できるのでこちらの方がオススメの記法です

@forelse ($users as $user)
    {{$loop->index}}

    @if ($loop->first)
        これは最初の要素です
    @endif

    @if ($loop->last)
        これは最後の要素です
    @endif

    <p>これは {{ $user->id }} ユーザーです。</p>
@empty
    ユーザーはいません
@endforelse

なお @empty は省略できません。
また、Laravel Blade の $loop->index0 から始まります。

● ファイルのインクルード(HTMLファイル内に記述)

※ Smarty

{include file="inc/header.html"}

※ Twig

{% include 'inc/header.html' %}

※ Laravel Blade

resources/views/user/mypage_sub_menu.blade.php を読み込みます

@include('user.mypage_sub_menu')

● if文(HTMLファイル内に記述)

※ Smarty

{if $flag==1 and hoge == 'myname'}
     hogehoge
{else}
    fugafuga
{/if}

※ Twig

{% if flag == 1 and hoge == 'myname' %}
     hogehoge
{% else %}
    fugafuga
{% endif %}

※ Laravel Blade

@if ( flag == 1 and hoge == 'myname' )
     hogehoge
@elseif ( flag == 2 )
     hogehoge2
@else
    fugafuga
@endif

● コメントアウト(HTMLファイル内に記述)

※ Smarty

{*
ここの間に記述したものはコメントアウトされ表示されません
*}

※ Twig

{#
ここの間に記述したものはコメントアウトされ表示されません
#}

※ Laravel Blade

{{--
ここの間に記述したものはコメントアウトされ表示されません
--}}

● 文字列のエスケープ(HTMLファイル内に記述)

※ Smarty(エスケープオプションは : html, htmlall, url, urlpathinfo, quotes, hex, hexentity, javascript, mail )

<a href="{$data|escape:'url'}">クリック</a>

※ Twig(エスケープオプションは : html, js, css, url, html_attr )

<a href="{{data|escape('url') }}">クリック</a>
<a href="{{data|e('url') }}">クリック</a> {# 【e】 だけでも OK #}

● 文字列のエスケープなし(HTMLファイル内に記述)

※ Laravel Blade

Hello, {!! $name !!}.

● 日付の表示(HTMLファイル内に記述)

※ Smarty

{* 2015-07-30 13:04:58 みたいな表示 *}
{$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}

※ Twig

{# 2015-07-30 13:04:58 みたいな表示 #}
{{ "now"|date("Y-m-d H:i:s") }}
{# TIMEZONE を指定することもできます #}
{{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }}

Twig の dateフィルタの 注意
データベースなどから持ってきた日付けを整形する場合はデータが存在するかどうかチェックしてから表示しないと、 データが存在しない場合に 現在の日付が表示されてしまいます

{{ "" | date("Y年m月d日") }} // 現在の日付が表示されます

例1 : if 文で判別する

{% if v.added_date != "" %}{{ v.added_date | date("Y/m/d H:i") }}{% endif %}

例2 : 三項演算子で表示する

{{ v.added_date is empty ? "" : v.added_date | date("Y/m/d") }}

● ホワイトスペースと改行をなくして1行で出力する(HTMLファイル内に記述)

※ Smarty

{strip}
<table>
 <tr>
  <td>
   test
  </td>
 </tr>
</table>
{/strip}

※ Twig

{% spaceless %}
<table>
 <tr>
  <td>
   test
  </td>
 </tr>
</table>
{% endspaceless %}

※ Laravel Blade ( PHPコードを直接記述する事ができます )

<?php $aaa = 999; ?>

● テンプレートファイル内で配列の長さを知る(HTMLファイル内に記述)

※ Smarty

{$test_loop|@count}

※ Twig

{{ test_loop |length }}

● 長い文字列を切り詰める(truncate)(HTMLファイル内に記述)

※ Smarty

{"abcdefghijklmnopqrstuvwxyz"|truncate:10}

※ Twig

Twigで truncate を使うには Twig-extensions をインストールします
https://github.com/twigphp/Twig-extensions
からダウンロードして Extensions ディレクトリを Twigディレクトリの下にアップロードし
PHPで $twig->addExtension( new Twig_Extensions_Extension_Text() ); とします。

{{"abcdefghijklmnopqrstuvwxyz"| truncate(20)}}

Twig_Extensions_Extension_Text : http://bit.ly/2jfkzXw

● 文字列の分割(explode, split)(HTMLファイル内に記述)

※ Smarty

{assign var="new_array" value=","|explode:$str_hoge} 

※ Twig

{% set new_array = "one,two,three"|split(',') %}

● 文字列の置換(replace)(HTMLファイル内に記述)

※ Twig

{{ "my name is hogehoge" | replace({hoge':'fuga'}) }}

● 文字列を逆にする(HTMLファイル内に記述)

※ Twig

{{ '1234'|reverse }}
{# outputs 4321 #}

● 文字列を切り出す(HTMLファイル内に記述)

※ Twig

{{ 123456 | slice(0, 2) }}

● 文字列の連結(HTMLファイル内に記述)

※ Smarty

{ 'sugoude'|cat:'DJ'|cat:'Master Key'}

※ Twig

{{ 'sugoude' ~ 'DJ' ~ 'Master Key' }}

連結した文字にフィルタをかける場合は、文字列を定義してからフィルタをかけましょう

× NG

{{ $hoge~$fuga|my_filter }}

◯ OK

{%set hogefuga = $hoge~$fuga%}
{{ $hogefuga|my_filter }}

● printf , sprintf(プリントフォーマット)(HTMLファイル内に記述)

※ Smarty

{ $value | string_format:"%02d" }

※ Twig

{{ "%02d" | format(value) }}

● テンプレートファイル名を取得する

※ Smarty

{$smarty.template}

※ Twig

{{ _self.getTemplateName().__toString }}

※ Gulp Twig と PHP Twig 両方に対応したファイル名取得

{# テンプレートファイル名 #}
{% if _target.relative %}{% set template_filename = _target.relative %}
{% else %}{% set template_filename = _self.getTemplateName().__toString %}
{% endif %}

● アプリのトップURIを取得

※ Laravel Blade

{{ url('/') }}

または

{{Request::root()}}

 Twig リファレンス : http://git.io/vneJa 

No.954
06/12 21:46

edit

Twig
Smarty
Gulp

PHPでMD5やSHA1などのハッシュ値を求める

PHPでは古くには md5() や sha1() などのハッシュを求める関数がありましたが 今のやり方では hash() 関数を使用します。

$output =  hash ( $algo , $data , $raw_output );
$algo
選択したアルゴリズムの名前 (すなわち "md5"、"sha256"、"haval160,4" など…)。

$data
ハッシュするメッセージ。

$raw_output
TRUE を設定すると、生のバイナリデータを出力します。 FALSE の場合は小文字の 16 進数値となります。

この関数で md5 SHA1 SHA256 アルゴリズムなどを選択して使用することができます。 使用できるアルゴリズムは以下

md2           32bit
md4           32bit
md5           32bit
sha1          40bit
sha256        64bit
sha384        96bit
sha512       128bit
ripemd128     32bit
ripemd160     40bit
ripemd256     64bit
ripemd320     80bit
whirlpool    128bit
tiger128,3    32bit
tiger160,3    40bit
tiger192,3    48bit
tiger128,4    32bit
tiger160,4    40bit
tiger192,4    48bit
snefru        64bit
gost          64bit
adler32        8bit
crc32          8bit
crc32b         8bit
haval128,3    32bit
haval160,3    40bit
haval192,3    48bit
haval224,3    56bit
haval256,3    64bit
haval128,4    32bit
haval160,4    40bit
haval192,4    48bit
haval224,4    56bit
haval256,4    64bit
haval128,5    32bit
haval160,5    40bit
haval192,5    48bit
haval224,5    56bit
haval256,5    64bit
No.948
06/08 15:11

edit

Smartyのプラグイン(modifier)に複数の引数を渡す

modifierプラグインは

{$hoge|my_modifier}

と記述すると、プラグインを記述した関数

function smarty_modifier_my_modifier($a){

}

$a に $hoge の内容が渡ります。


■ modifierプラグインに複数の引数を渡すには

{$hoge|my_modifier:'arg1':'arg2'}

と記述します。

すると

function smarty_modifier_my_modifier($a, $b, $c){

}

$a に $hoge が

$b に 'arg1' が

$c に 'arg2' が

渡ります

No.943
05/12 12:43

edit

Smarty

PHPでファイルをダウンロードさせる

PHPでファイルをダウンロードさせるにはブラウザにダウンロードファイルを知らせるためのヘッダとファイル名を送ります

例 : test.csv というファイル名でダウンロードさせる

header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=test.csv");
print 'ファイル内容';
No.932
04/20 16:24

edit

ファイル

PHPのforeachループ内で「配列の最初かどうか?」「最後かどうか?」を調べる

PHPでforeachループで回している時に、配列の先頭かどうか?最後かどうか?を調べるには次のようにします。

foreach ($hash as $k => $v) {
    if (reset(array_keys($hash)) === $k) {
        print "先頭の要素です";
    }
    if (end(array_keys($hash)) === $k) {
        print "最後の要素です";
    }
}
No.926
02/23 16:27

edit

配列

PHPでPDFを生成する【FPDF】

(こちらに記述してあるのはFPDFを使った古いやり方です。TCPDFを使った新しいやり方はこちら↓)
http://logic.moo.jp/data/archives/967.html

●FPDFのダウンロード

FPDF Version 1.7
http://www.fpdf.org/en/dl.php?v=17&f=zip
(ZIPファイルをダウンロードできるので解凍します。)

最新バージョンはこちらから確認して下さい。
http://www.fpdf.org/

● FPDFのインストール

サーバ上にフォルダ 【fpdf】 を作りそこに

fpdf.php
「fontフォルダ」
「makefontフォルダ」

をアップロード

● FPDFの実行

require_once 'fpdf/fpdf.php';
$pdf=new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',16);
$pdf->Cell(40,10,'Hello World! FPDF Sample !!');
$pdf->Output();	

でブラウザにpdfファイルが表示されます。

No.915
06/28 13:54

edit

pdf

PHPで文字列を数値型に変換する。

PHPで文字列を数値型に変換するには intval() を使用します。

// クォーテーションで囲って文字列型の変数を生成
$str = "99";
// 文字列型を数値型に変換する
$num = intval($str);
No.910
01/25 18:22

edit

PHPで文字コードを指定したヘッダを返す

PHPで文字コードを指定したヘッダを返すには以下のようにします。

// UTF-8 の場合
header("Content-type: text/html; charset=UTF-8");
// Shift-JISの場合
header("Content-type: text/html; charset=Shift_JIS");
// euc-jp
header("Content-type: text/html; charset=euc-jp");

またPHPで明示的に文字コードを設定したい場合はもともとのPHP設定でエンコーディングが明確に指定されていない場合が多いです。

ですので以下のようにまとめて設定するといいでしょう

PHP文字コード関連をまとめて設定(PHP 5.6対応)

$encoding = 'UTF-8';
mb_internal_encoding($encoding);
$pv = floatval(phpversion());
if ($pv <= 5.5){ ini_set('mbstring.internal_encoding', $encoding); }
ini_set('mbstring.script_encoding', $encoding);
header("Content-Type: text/html; charset={$encoding}");

No.899
08/10 17:12

edit

PHPでSQLite3を扱う

PHP5.3以降からSQLite3を扱うクラスが用意されています。

これを使うとSQLiteの操作がとても簡単なのでこちらで紹介します。

■1. PHPからSQLite3のデータベース(test.db)テーブル(test_tbl)を作成する

<?php
// 作成するデータベース名
$db_name = 'test.db';
// 作成するテーブルのSQL
$sql = <<<DOC_END
CREATE TABLE test_tbl (
	test_id    INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
	test_name  TEXT
)
DOC_END;
// INSERTするデータのSQL
$sql2 = <<<DOC_END
INSERT INTO test_tbl(test_id, test_name) VALUES(1, '細野晴臣');
INSERT INTO test_tbl(test_id, test_name) VALUES(2, 'ほそのはるおみ');
INSERT INTO test_tbl(test_id, test_name) VALUES(3, 'ホソノハルオミ');
DOC_END;

try {
  $db = new SQLite3($db_name);
} catch (Exception $e) {
  print 'DB接続エラー。<br>';
  print $e->getTraceAsString();
}
$db->exec( $sql );
$db->exec( $sql2 );
$db->close();
?>

なおSQLiteでデータベースのカラムに指定できる「型」は次の5つ

TEXT
NUMERIC
INTEGER
REAL
NONE

DATEやDATETIME型は存在しないのでTEXT型で処理するのがいいでしょう。


■2. PHPでSQLite3データベースのデータを取得(SELECT)する

<?php
$encoding = 'UTF-8';
mb_internal_encoding($encoding);
ini_set('mbstring.internal_encoding', $encoding);
ini_set('mbstring.script_encoding', $encoding);
header("Content-Type: text/html; charset={$encoding}");

// 接続するデータベース名
$db_name = 'test.db';

try {
  $db = new SQLite3($db_name);
} catch (Exception $e) {
  print 'DB接続エラー。<br>';
  print $e->getTraceAsString();
}

$results = $db->query('SELECT * FROM test_tbl');
print '<pre>';
while ($row = $results->fetchArray(SQLITE3_ASSOC)) {
  print_r($row);
  print '<br>';
}
print '</pre>';

$db->close();
?>

■3. 知っておくと便利なSQLiteのSQL文

あるテーブル(test_tbl)の構造を取得する

PRAGMA table_info(test_tbl);

全てのテーブルを表示する(MySQLでいうところの show tables; )

select name from sqlite_master where type = 'table'

auto increment の値をリセットする

update sqlite_sequence set seq=1 where name='テーブル名';

■4. SQLite のSQL文を実行するプログラム(PHP)

https://pgmemo.tokyo/data/filedir/897_1.zip

↑ このファイルをダウンロードして自分のサーバ上にて実行してください。

SQL文入力画面が表示されます。

■5. SQLite (拡張子 .db のファイル)を直接操作するアプリ【Lita】【sqlitebrowser】

■ Lita

http://www.dehats.com/drupal/?q=node/58

■ sqlite browser

http://sourceforge.net/projects/sqlitebrowser/

データベースファイル( *.db )を直接開くと色々操作できます。とても便利。

<b>(※注意 なおWEBサービス運用中のデータベースファイルを開く時はコピーして別名で操作することをおすすめします)</b>

■6. SQLite (拡張子 .db のファイル)を直接操作するFirefoxアドオン【SQLite Manager】

https://addons.mozilla.org/ja/firefox/addon/sqlite-manager/

既存のデータを残しつつテーブル構造を変更するときはこのアドオンが便利です。

■7. MySQLのSQL文をSQLite用に変換する

http://flatsystems.net/js_mysql_to_sqlite.html

添付ファイル1

PHPからTwitter API 1.1 を使って Twitterに自動書き込みする。【tmhOAuth】

■ tmhOAuth

https://github.com/themattharris/tmhOAuth

↑ ここからダウンロードして tmhOAuth.php をサーバにアップします。

■ コーディング例(自分のアカウントに hoge hoge hoge とつぶやきます。)

require_once 'tmhOAuth.php';
$twitter = new tmhOAuth(
	array(
		'consumer_key'        => 'aaaaa' ,
		'consumer_secret'     => 'bbbbb' ,
		'token'               => 'ccccc' ,
		'secret'              => 'ddddd' ,
		'curl_ssl_verifypeer' => false ,
		'timezone'            => 'Asia/Tokyo' ,
	)
);
$r = $twitter->request('POST', $twitter->url('1.1/statuses/update'), array(
	'status' => 'hoge hoge hoge'
), true, false);
// 正常終了なら $r に 200 が返る。 
print '<pre>'; print_r($twitter); print '</pre>';

■ Twitter REST API v1.1 Resources (ツイッターAPIのリファレンス)

https://dev.twitter.com/docs/api/1.1


その他参考:

tmhOAuth を使って twitter に画像つきつぶやきを投稿するには

No.891
06/25 17:16

edit

API
Twitter

PHPでメールアドレスのチェックを【filter_var】【正規表現】で行う。

PHP5.2から filter_var というメールアドレス等をチェックする関数が追加されています。

filter_var でのメールアドレスのチェック

filter_var('bob@example.com', FILTER_VALIDATE_EMAIL);

便利なのですが昔の日本の携帯アドレスはRFC準拠していなくても使えていたみたいですし、そういったアドレスはエラーとされてしまいます。

それなら正規表現のほうがカスタマイズがきいていいような気がします。

正規表現でのメールアドレスチェッククラス【AddressValidate.php】

PHPのメジャーフレームワークの正規表現を網羅してクラス化してあります。便利!

http://d.hatena.ne.jp/m-tag/20081118/1227000201

PHPメジャーフレームワークの正規表現

CakePHP 1.2

/^[a-z0-9!#$%&'*+\/=?^_`|~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`|~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[a-z]2,4|museum|travel)$/i

CakePHP 1.3

/^[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+)*@(?:[-_a-z0-9][-_a-z0-9]*\.)*(?:[a-z0-9][-a-z0-9]{0,62})\.(?:(?:[a-z]{2}\.)?[a-z]{2,4}|museum|travel)/i

Ethna

/^([a-z0-9_]|\-|\.|\+)+@(([a-z0-9_]|\-)+\.)+[a-z]{2,6}$/i

正規表現がチェックできるサイト

http://www.rubular.com/


Perlの場合CPANの Email::Valid を使うのがいいでしょう

http://search.cpan.org/search?query=Email%3A%3AValid&mode=all


参考

http://d.hatena.ne.jp/j0hn/20070602

http://d.hatena.ne.jp/m-tag/20081118/1227000201

添付ファイル1
No.889
08/12 10:29

edit

添付ファイル

正規表現
メール

外部SMTPサーバを利用してメールを送信する。

外部SMTPサーバを利用してメールを送信するには PEAR:Mail を利用します。

必要な PEAR パッケージ(ダウンロードしてサーバ上にアップ)

( PEAR:Mail )

( PEAR:Net:SMTP )

( PEAR:Net:Socket )

PHPコードは以下のように記述します。

『例』

送信元 : xxxxx@hoge.com

送信先 : xxxxx@fugafuga.com

使用するSMTPサーバ : mail.fugafuga.com

ユーザー名 : xxxxx@fugafuga.com

パスワード : aiueoaiueo

$to = 'xxxxx@hoge.com';
$from = 'xxxxx@fugafuga.com';
$mailtext = 'メール送信テスト';

// PEAR:Mail
require_once "Mail.php";
$params = array(
  'host' => 'mail.fugafuga.com',
  'port' => '587',
  'auth' => true,
  'username' => 'xxxxx@fugafuga.com',
  'password' => 'aiueoaiueo',
);		
$headers['From']    = $from;
$headers['To']      = $to;
$headers['Subject'] = mb_encode_mimeheader($subject);
$mailtext = mb_convert_encoding($mailtext, "ISO-2022-JP", "auto");
$objMail =& Mail::factory('smtp', $params);
$result = $objMail->send($to, $headers, $mailtext);
if (PEAR::isError($result)) {
	die($result->getMessage());
}

その他のクラスとしては

phpmailer : https://packagist.org/packages/phpmailer/phpmailer

がおすすめです

No.881
03/08 20:32

edit

メール
PEAR

日本語(全角文字)を指定文字数で折り返す(word wrap)Smartyプラグイン

ある文章を指定文字数折り返(強制改行)したい時があります。

そんな時に便利なのがSmartyのwordwrapプラグインがありますが、日本語や全角文字には対応していないので使用出来ません。

そこで日本語対応のSmartyプラグイン

■ modifier.unicode_wordwrap

(引用元:http://goo.gl/JmZjK にインデント機能を拡張しました。)

ファイル名 modifier.unicode_wordwrap.php で下記コードを保存し plugins フォルダに格納

<?php
function smarty_modifier_unicode_wordwrap($str, $len=80, $break="\n", $indent='' ){
	$str = str_replace( "\r", $break, str_replace( "\r", "\n", str_replace("\r\n", "\n", $str) ) );
	$str = preg_replace('/(.{'.$len.'})/u', '${1}'.$break, $str);
	if (strcmp($indent,'')==0){ return $str; }
	else{
		$ar  = preg_split("/{$break}/",$str);
		for($i=0 ; $i<count($ar); $i++){
			$ar[$i] = $indent.$ar[$i];
		}
		return join($break, $ar);
	}
}
?>

使い方

下記の例だと($my_text を日本語40文字で折り返して各業の文頭に■を追加)となります。

{$my_text|unicode_wordwrap:40:"\n":"■"}

第1引数 : 文字数(デフォルト値:80)
第2引数 : 改行コード(デフォルト値:¥n)
第3引数 : インデント(デフォルト値:ナシ)

です。

No.873
02/06 16:23

edit

Smarty
日本語

phpの実行時間を計測する

PHPの実行時間を計測するには下記ような方法で計測します。

$start_time = microtime(true);

// ここに計測したい処理を記述

$end_time        = microtime(true);
$processing_time = $end_time - $start_time;

echo "開始時間: ".format_microtime($start_time,'Y-m-d H:i:s')."<br>\n";
echo "終了時間: ".format_microtime($end_time,'Y-m-d H:i:s')."<br>\n";
echo "処理時間:".format_microtime($processing_time)."秒<br>\n";
function format_microtime ( $time, $format = null )
{
	if (is_string($format)) {
		$sec  = (int)$time;
		$msec = (int)(($time - $sec) * 100000);
		$formated = date($format, $sec). '.'. $msec;
	} else {
		$formated = sprintf('%0.5f', $time);
	}
	return $formated;
}
No.859
10/18 11:08

edit

高速化

Smartyテンプレート内で乱数(ランダム文字列)を発生させる

例えば管理画面で画像をキャッシュさせたくない場合など

Smartyテンプレート内で乱数(ランダムな文字列)を発生させて

<img src="test.jpg?123">

などとするといいでしょう。

そこで乱数を発生させるには

{0|rand:999}

つまり

<img src="test.jpg?{0|rand:999}">

となります。

No.845
11/01 11:43

edit

Smarty

UTF-8を使った正規表現でエラー「this version of PCRE is not compiled with PCRE_UTF8」の場合の対応

PHPで UTF-8 を使った正規表現の命令時 ( preg_match('test/u', $str); )に

以下のようなエラー

Compilation failed: this version of PCRE is not compiled with PCRE_UTF8 support

が出ることがあります。

これは「PCREがUTF-8をサポートしていないときに出るエラーです。」

PCREのサポート状況を知るにはコマンド【pcretest -C】を実行するか、

pcretest.php を以下の内容で保存してWEBブラウザから実行します。

pcretest.php

<?php
print '<pre>';
print '<h1>実行コマンド:pcretest -C</h1>';
print ( shell_exec('pcretest -C') );
print '</pre>';
?>

これでUTF-8サポートがなければ再度PCRE, PHPをコンパイルしましょう。

レンタルサーバの場合は仕方ないので preg_match などの /u オプションを取り除いたコーディングとしましょう。



No.839
03/21 22:46

edit

正規表現にマッチするかどうか判別する Smarty Plugin

正規表現にマッチするかどうか判別する Smarty Plugin。

ファイル名 modifier.ext_preg.php で以下のとおり作成

<?php
function smarty_modifier_ext_preg($string='', $preg_pattern=''){
	if (strcmp($string,'')==0 || strcmp($preg_pattern,'')==0){ return false; }
	if (preg_match($preg_pattern, $string)){
		return true;
	}
	else{
		return false;
	}
}

使い方 ( $file にファイル名が入っているものとします )

{ if $file|ext_preg:'/(mp4$)/i' }動画です
{ elseif $file|ext_preg:'/(gif$|jpg$|jpeg$|png$|bmp$)/i' }画像です
{ /if }
No.837
09/17 12:44

edit

Smarty

PHPで安全なファイルロック

PHPでファイルロック(排他制御)をするのは標準の flock 関数が簡単で有効です。
しかし flock関数はサーバーによっては正常動作しない(排他制御が出来ない、またはロックしたままプロセスが死 ぬとロック解除が出来ない)ことがまれにあります。(サーバーによります。)
ですのでPHPスクリプトをアップロードする先のサーバーが flock が正常に動作するか毎回確認しないといけませ ん。
また flock関数ではロックのトライ時間(タイムアウト時間)を自由に設定することができません。
そこで Perlメモ( http://is.gd/cKqS11 )の有名なファイルリネーム方式のファイルロックを採用します。
すでにPHPに移植されている方がいるのでそこから引用( http://is.gd/rj4aOc )

● ダウンロード

https://pgmemo.tokyo/data/filedir/834_3.zip

● 使い方

require_once('exfilelock.php');
$exfl = new exfilelock();
$exfl->flock() or die('ERROR : LOCK ERROR');

// ここに排他制御して実行したい何かしらの処理を記述

$exfl->unflock() or die('ERROR : UNLOCK ERROR');

**ファイルロックのテストスクリプト

test_filelock.php:ロックを使ったカウンターアップのテスト

ファイルを解凍してできるディレクトリ「data」「lockdir」のパーミッションを777にして abで同時に100並列実行します。 カウンターが正常に10000までいけばOK。

ab -n 100 -c 100 http://mitoite.net/test/php_mailform/php_mailform.php?cmd=append_imap
添付ファイル1
添付ファイル2
No.834
05/12 13:48

edit

添付ファイル

ファイル

画像ファイルの width, height を取得して挿入するSmarty Plugin

画像ファイルの width, height を取得して挿入するSmarty Plugin

ファイル名 : modifier.image_wh.php で保存

<?php
function smarty_modifier_image_wh($file_name='') {
    if (! $file_name ) { return "error:{$file_name}"; }
    if (!is_file($file_name)) { return "error:{$file_name}"; }
    list($width, $height, $type, $attr) = getimagesize($file_name);
    if ($width && $height){
        return 'width="' .$width. '" height="'.$height.'"';
    }
    else{
        return "error: can not get width height:{$file_name}";
    }
}

使い方

<img src="{$image_file}" {$image_file|image_wh} />{/if}

とすると width="100" height="200" といった情報が入ります。

なお変数に入ったディレクトリも指定する場合は

{$image_file|image_wh}
  ↓
{"`$data_dir`/`$image_file`"|image_wh}

とします。


No.833
01/05 11:43

edit

Smarty
画像
ファイル

拡張子 .html でphpを動かす

.htaccess ファイル内に以下の内容を作成して動作させたいフォルダに置きます。

php5の場合

AddHandler php5-script .php .html

php4の場合

AddHandler application/x-httpd-php .php .html

No.831
07/14 14:07

edit

.htaccess

PHPのオブジェクトを連想配列に変換する

PHPのオブジェクトを連想配列に変換するには。

private function obj_to_array( $obj ){
    return json_decode(json_encode($obj), true);
}
$my_array = $this->obj_to_array($obj);

とします。

No.827
05/15 11:42

edit

PHPでURLからローカルにファイルをダウンロードする

PHPでURLからローカルにファイルをダウンロードするには以下のようにします。

function file_download($url, $dir='.', $save_base_name='' ){
	if ( ! is_dir($dir) ){ die("ディレクトリ({$dir})が存在しません。");}
	$dir = preg_replace("{/$}","",$dir);
	$p = pathinfo($url);
	$local_filename = '';
	if ( $save_base_name ){ $local_filename = "{$dir}/{$save_base_name}.{$p['extension']}"; }
	else{ $local_filename = "{$dir}/{$p['filename']}.{$p['extension']}"; }
	if ( is_file( $local_filename ) ){ print "すでにファイル({$local_filename})が存在します<br>\n";}
	$tmp = file_get_contents($url);
	if (! $tmp){ die("URL({$url})からダウンロードできませんでした。");}
	$fp = fopen($local_filename, 'w');
	fwrite($fp, $tmp);
	fclose($fp);
}

実行は

// ■1. ファイル名「hogehoge.jpg」でディレクトリ「images」に保存する場合
file_download('http://www.xxx.xxx.jp/hogehoge.jpg', 'images');

// ■2. ファイル名「0001.jpg」でディレクトリ「images」に保存する場合
file_download('http://www.xxx.xxx.jp/hogehoge.jpg', 'images', '0001');
No.825
01/19 16:51

edit

ファイル

PHPで画象を切り抜き・縮小しサムネイルを作成する

PHPで画象を切り抜き・縮小し、サムネイルを作成するには次のパッケージを使用するのが簡単でおすすめです。

● 画像切り抜きパッケージ

intervention/image - Packagist(★6067)
eventviva/php-image-resize - Packagist(★425)

● intervention/imageの使い方

1. intervention/image のインストール

composer require intervention/image

2. intervention/image の使い方

use Intervention\Image\ImageManagerStatic as Image;

require_once __DIR__ . '/vendor/autoload.php';

// Resize By intervention/image
$img = Image::make("myfile.jpg");
$img->fit(600, 800);
$img->save("myfile.jpg");

● eventviva/php-image-resizeの使い方

1. eventviva/php-image-resize のインストール

composer require eventviva/php-image-resize
use \Eventviva\ImageResize;
// Resize By eventviva/php-image-resize
$image = new ImageResize("myfile.jpg");
$image->crop(600, 800);
$image->save("myfile.jpg");

どちらもおすすめです。

添付ファイル1
No.800
01/11 18:06

edit

添付ファイル

画像

Googleサジェスト(Yahoo, Bing, Amazon, Youtubeも)APIを使用する

Googleサジェストや他の検索エンジンやアマゾンのサジェストをPHPで使用するには下記のように記述します。

($url = ''; の定義を複数行記述していますので、使用したいAPI以外の行をコメントアウトしてください。)

$text   = 'ジャズ';
// Google
$url = 'http://suggestqueries.google.com/complete/search?hl=ja&qu='.urlencode($text);
// Youtube
$url = 'http://clients1.google.com/complete/search?hl=en&ds=yt&client=firefox&q='.urlencode($text);
// Amazon
$url = 'http://completion.amazon.co.jp/search/complete?method=completion&search-alias=aps&mkt=6&q='.urlencode($text);
// Yahoo
$url = 'http://asprov.search.yahoo.co.jp/AssistSearchService/V2/webassistSearch?output=iejson&callback=ytopAssist&p='.urlencode($text);
// Bing
$url = 'http://api.bing.net/osjson.aspx?FORM=OPERAS&Market=ja&Query='.urlencode($text);
$json = file_get_contents($url);
$json = mb_convert_encoding($json, 'UTF8');
$data = json_decode($json,true);
print "<pre>";
print_r($data);
print "</pre>";

Bingでの使用例(「ジャズ」という単語でサジェストした結果)

Array
(
    [0] => ジャズ
    [1] => Array
        (
            [0] => ジャズドリーム
            [1] => ジャズドリーム長島
            [2] => ジャズダンス
            [3] => ジャズドリーム長島 クーポン
            [4] => ジャズピアノ
            [5] => ジャズドリーム長島 セール
            [6] => ジャズ 名曲
            [7] => ジャズマスター
        )
)

となります。

No.792
04/26 10:52

edit

API

phpのソースコードから不要なコメント、スペースを削除してきれいに整形する

phpのソースコードから不要なコメント・スペース・改行を削除するには下記のコマンドが有効です(シェルのコマンドラインやターミナルから実行)

mysource.php から不要なコメント・スペース・改行を削除

php -w mysource.php > mysource_min.php

これだけです。簡単。

改行も削除されてプチ難読化されたコードになります。

これでは読みづらい、という場合は php_beautifier を使って読みやすいコードに変換します。

■ PEAR PHP_Beautifier

http://pear.php.net/package/PHP_Beautifier/download

php_beautifier -t mysource_min.php > mysource_beautifier.php
# -t オプションを指定して タブによるインデントを加えています(デフォルトはスペース4つ)

php_beautifierコマンドがうまく動かない場合は

直接ダウンロードして

http://pear.php.net/package/PHP_Beautifier/download

解凍して出来たフォルダの「scripts」フォルダ内の「php_beautifier」を動かせば動作します

php php_beautifier 【整形したいphpソース】 >【出力ファイル名】

■ php_packer.php

下記 php_packer.php をダウンロードして

php_packer.php -i ファイル名(またはディレクトリ名)

でディレクトリごと一括で処理できます。

添付ファイル1
No.784
10/26 13:12

edit

添付ファイル

PEAR

Googleの短縮URLサービスAPI goo.gl をPHPから使用する

Googleの短縮URLサービス goo.gl をPHPから使用するには以下のようなコードで実現できます。

1. APIキー( api_key )を取得する

https://code.google.com/apis/console/

ここから取得できます

2. 以下のPHPコードで実現できます( $api_key に取得したキーをセットすること )

function get_tiny_url($long_url=''){
	$api_url = 'https://www.googleapis.com/urlshortener/v1/url';
	$api_key = 'XXXXXXXXXXX';
	$curl = curl_init("$api_url?key=$api_key");
	curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/json'));
	curl_setopt($curl, CURLOPT_POST, 1);
	curl_setopt($curl, CURLOPT_POSTFIELDS, '{"longUrl":"' . $long_url . '"}');
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
	$res = curl_exec($curl);
	curl_close($curl);
	$json = json_decode($res);
	$tiny_url = $json->id;
	return $tiny_url;
}

使い方

$long_url = 'http://xxxx.xxxx.xxx.com/xxxxxxxxxxxxxx.html';
$tiny_url = get_tiny_url($long_url);

No.781
04/04 17:46

edit

API
URL

PHP(PEAR:HTTP_OAuth)でTwitter等各種サービスにOAuthログインをする。

PEARでTwitter等各種サービスにOAuthログインをする。(https SSL対応)

必要なPEARパッケージを下記からダウンロードする

面倒な方は

http://logic.moo.jp/memo.php?cmd=download&data_id=780&file=780_1.zip

をダウンロードして(lib)フォルダをそのままコピーしてください。

Twitterにアプリケーションを登録して「Consumer key」「Consumer secret」を取得する

https://twitter.com/apps

【新しいアプリケーションを追加】を押して、アプリ情報を入力して登録を完了させる。

登録完了後に表示される画面から

・Cunsumer Key
・Consumer secret
・Request token URL (フォローをリクエストしました)
・Access token URL
・Authorize URL

をメモしておく

後は下記コードにメモした情報をコピペすればOK($callback_url にはプログラムのURLをセットする。)

$path = './lib';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
include 'HTTP/OAuth/Consumer.php';
$consumer_key      = 'XXXXXXXXXX';
$consumer_secret   = 'XXXXXXXXXX';
$get_request_token = 'https://twitter.com/oauth/request_token';
$get_access_token  = 'https://twitter.com/oauth/access_token';
$get_authorize     = 'https://twitter.com/oauth/authorize';
// $get_authorize     = 'https://twitter.com/oauth/authenticate'; // 毎回出る
認証画面をskipしたい時
$callback_url      = 'XXXXXXXXXX';
$oauth = new HTTP_OAuth_Consumer($consumer_key, $consumer_secret);
// ssl証明書
$http_request = new HTTP_Request2();
$http_request->setConfig('ssl_verify_peer', false);
$oauth_request = new HTTP_OAuth_Consumer_Request;
$oauth_request->accept($http_request);
$oauth->accept($oauth_request);
$oauth_flag = false;
session_start();
if (empty($_SESSION['oauth_access_token']) && empty($_GET['oauth_verifier'])) {
	// 1. 初回呼び出し時
	$oauth->getRequestToken($get_request_token, $callback_url);
	$_SESSION['oauth_request_token'] = $oauth->getToken();
	$_SESSION['oauth_request_token_secret'] = $oauth->getTokenSecret();
	$_SESSION['oauth_state'] = "start";
	$auth_url = $oauth->getAuthorizeURL($get_authorize);
	// header("Location: $auth_url");					// A. リダイレクト
	print('<a href="'.$auth_url.'">'.$auth_url.'</a>');	// B. リンク表示
}
elseif( isset($_GET['oauth_verifier']) ){
	// 2. サービスから帰ってきたとき
	$oauth->setToken($_SESSION['oauth_request_token']);
	$oauth->setTokenSecret($_SESSION['oauth_request_token_secret']);
	$oauth->getAccessToken($get_access_token, $_GET['oauth_verifier']);
	$_SESSION['oauth_access_token'] = $oauth->getToken();
	$_SESSION['oauth_access_token_secret'] = $oauth->getTokenSecret();
	$oauth_flag = true;
}
else{
	// 3. 認証後にアクセスしたとき
	$oauth_flag = true;
}
if ( $oauth_flag ){
	// ここにやりたい事を記述
	print '<h1>OAUTH OK !</h1>';
}

サンプルコードを実行する

サンプルコードは以下のリンクからダウンロードして下さい。

添付ファイル1
No.780
04/08 18:28

edit

添付ファイル

Twitter
PEAR

PHPでumaskの設定を行う

UNIX系OSでファイルの処理を行うときに必ず気を付けないといけないのがumask。

これはファイル処理を行うときのパーミッション(権限)を指定しておくものです。

まずumaskの確認

printf ("%03o",umask());

結果

022

と帰ってくることが多いと思います。

この状態で新規ファイルを作成するとパーミッションは【644】となります。

新規に作成するファイルのパーミッションを【666】にしたければ

あらかじめ

umask(0000);

としておけばいいでしょう。

No.776
04/11 18:31

edit

ファイル

PHPで多次元配列(ハッシュの配列)を並び替える、またはランダム順にする。

データベースから取得したデータをPHP内で並べ替えたり、ランダムに並び替えたい時があります。 関数【array_multisort】を使ってタイトルでソートするには以下のようにすればOKです。

$loop = array(
    array(
        'id' => 1,
        'title' => 'あいうえお',
    ),
    array(
        'id' => 2,
        'title' => 'かきくけこ',
    ),
    array(
        'id' => 3,
        'title' => 'さしすせそ',
    ),
);
$ids = array();
foreach ($loop as $value) {
    array_push($ids,$value['title']);
}
// shuffle($ids);   // もしランダムにソートする場合はこのコメントアウトを解除する
array_multisort($ids, SORT_DESC, $loop);

実際には次のように実装します

    /**
     * このメソッドはハッシュの配列を任意のカラムでソートします(大きい順 DESC )
     *
     * @param   array       $loop
     * @param   string      $column_name
     *
     * @return  array       $loop
     */
    public function loop_sort( $loop, $column_name ){
        $ids = array();
        foreach ($loop as $value) {
            array_push($ids,$value[$column_name]);
        }
        array_multisort($ids, SORT_DESC, $loop); // 小さい順にする時は SORT_ASC
        return $loop;
    }

次のように呼び出します。(titleでソートする場合)

$sorted_loop = $this->loop_sort( $original_loop, 'title' );

簡単ですね!

No.775
07/10 17:45

edit

配列
ソート

Smartyキャッシュを削除する

Smartyキャッシュを削除するには clear_cache(); を使用します。

void clear_cache(string template,
                 string cache_id,
                 string compile_id,
                 int expire_time);

Smartyを使用したサイトではSmartyキャッシュを使用することにより劇的に高速化されますが、(テストページや一時的に表示したページの)キャッシュファイルをクリアし忘れると、逆にハードディスクに負荷をかけて動作を遅くするおそれがあります。

古い不要キャッシュの削除は必ず行いましょう。

Smarty Cache時間による自動削除の例

// 7日以上古いキャッシュを削除する
$days = 7;
$time = $days * 24 * 60 * 60;
// 10回に1回実行
if( rand(1,10)==1 ){ $smarty->clear_all_cache($time); }

ファイルを使用せずキャッシュにMySQLを使用する

http://www.smarty.net/docsv2/ja/section.template.cache.handler.func.tpl

No.761
08/23 10:43

edit

Smarty
ファイル
高速化

PHPでHTMLタグの閉じ忘れを修正する PECL::Tidy

TidyとはHTMLタグの閉じ忘れを直したりHTML修正を行う便利なソフトです。

Xpathでスクレイピングを行うときにHTMLが完璧でないと正しく取得できないので事前に整形を行います。

なおPECL拡張なのでインストールにはサーバー管理者権限が必要です。

インストールは yum で

yum install php-tidy

apache再起動

apachectl graceful

実際のソースは下記のように記述します。

$html = '<html><body><p>タグの閉じ忘れテスト</body></html>';
if ( ! in_array('tidy',get_loaded_extensions(), true )){
 die('このサーバではtidyが使用できません');
}
$config = array('indent' => false,
                'output-xhtml' => TRUE,
                'wrap' => 200);
$tidy = tidy_parse_string($html, $config, 'UTF8');
$h = tidy_get_html($tidy);
$html = $h->value;

以上の簡単なコードで実現できますが、整形するソースファイルが大きいとメモリ、プロセス共に大量に使用するので注意。

$configに設定できるオプションはこちら

http://tidy.sourceforge.net/docs/quickref.html

No.758
07/13 10:10

edit

Xpath

phpで画像ファイルの拡張子を判別する

1. phpで画像の拡張子を取得するには

$ext = pathinfo($filename, PATHINFO_EXTENSION);

2. phpでファイルのディレクトリを取得するには

$ext = pathinfo($filename, PATHINFO_DIRNAME);

3. phpでファイルの拡張子を取り除いたファイル名を取得するには

$filename_only = pathinfo($original_file_name, PATHINFO_FILENAME);

です。

No.751
07/20 15:52

edit

ファイル
画像

PHPでHTTPのステータスコード(404 、 301など)を返す。

HTTPステータスコードとは、ブラウザがリクエストを送信したときに受け取るコードです。

(通常目にすることはありません。 firefox LiveHTTPHeaderなどで確認します。)

HTTPステータスコードの例

301 Moved Permanently
303 See Other
403 Forbidden
404 Not Found

PHPでステータス 301 Moved Permanently を返すには。

header('Status: 301 Moved Permanently');
header('Location: http://hogehoge.com');
exit;

とします。

PHPでステータス 404 Not Found を返すには。

header("HTTP/1.1 404 Not Found");
include ('404.php');
exit;

とします。

404の場合はステータスを返した後に 404.php(ファイル名は任意)というphpを実行します。

(でないと画面が真っ白になる)

404.phpの例(404.html というファイルの中身をそのまま表示する)

<?
$filename = '404.html';
$fp = fopen($filename,'r') or die("ファイル({$filename})のオープンに失敗しました");
while (!feof($fp)) {
$line = fgets($fp, 1024);
print "$line\n";
}
fclose($fp);
?>
No.746
08/18 16:27

edit

PHPでXMLのXSLT変換を行う。

XMLファイルからHTMLファイルを作成したい時、XSLTを使うと早い場合があります。

そのサンプル

<?php
$xml = new DomDocument();
$xml->load('test.xml');
$xsl = new DomDocument();
$xsl->load('sample01.xsl');
$processor = new xsltprocessor();
$processor->importStyleSheet($xsl);
echo $processor->transformToXML($xml);
?>

XSLT書式

http://vosegus.org/guideline/xslt.html

例:そのノードのテキストが hoge の場合のみ ZZZZZZZZZ を表示する

<xsl:if test="contains(./text() , 'hoge')">
ZZZZZZZZZ
</xsl:if>

襟:デフォルト値をセットする

<xsl:param name="contents">デフォルト値</xsl:param>
No.741
04/08 10:00

edit

Xpath
XML

PHPで顔認識 openCV

画像ファイルに人物(顔が含まれるかどうか?)を判断するには openCV というのを使用します。

openCVのインストール

yum -y install opencv

re2cのインストール(インストールされている場合はスキップ)

tar zxvf re2c-0.12.2.tar.gz
cd re2c-0.12.2
./configure
make
su
make install

PHP拡張をインストール

http://hirokawa.netflowers.jp/entry/4874/

apacheを再起動

apachectl graceful


No.731
10/19 09:31

edit

画像

phpでxpathを使ってスクレイピング(WEBページの取得)とXpathの書式例

■ 1. まず php-xml のインストール

yum install php-xml

■ 2. 実際のサイトからスクレイピングを行って Xpath で要素を取得のPHPコード

test.server.com から WEBページを取得してきて<div id="myid">の要素を取得します。

$url='http://test.server.com';
// file_get_contents を使うより高速、ただしメモリは食う
require_once 'HTTP/Client.php';
$client =& new HTTP_Client();
$client->get($url);
$response = $client->currentResponse();
$dom = @DOMDocument::loadHTML( $response['body']);
$xml = simplexml_import_dom($dom);
$t = $xml->xpath('id("myid")');
if (! $t){ die('xpath error'); }
print_r( $t );

■ 3. Xpath書式例

全要素

//*	または /descendant::*

全 div 要素

//div	または /descendant::div

HTMLページのタイトル

//html/head/title

全 li または div 要素

//*[name()='li' or name()='div' ]

class 属性が 'hoge' な div 要素(完全一致)

//div[@class='hoge']	/descendant::div[@class='hoge']

class 属性が 'hoge fuga' な div 要素(完全一致)

//div[@class='hoge fuga']
//div[contains(@class ,'hoge') and contains(@class ,'fuga')]

class 属性に 'list' を含む div 要素(部分一致)

//li[contains(@class,'list')]

そのノードのテキストの取得

//div[@class='hoge']/text()

そのノード以下の全てのテキストの取得

//div[@class='hoge']/.

id 属性が 'hoge' な要素 → id('hoge')と書くのが高速ですがPHPではうまく取得できないこともあります

id('hoge')
//*[@id='hoge']
/descendant::*[@id='hoge']

テキストが 'hogehoge' なdiv要素(完全一致)   例:<div>hogehoge</div>

//div[text()='hogehoge']

テキストが 'fuga' を含むdiv要素(部分一致)

//div[contains(text(), "fuga")]

【thタグ内のテキストが'fuga'】なthを持つ tr

//table//tr[th[text()='fuga']]

title 属性が 'hoge' で class 属性が 'fuga' でない要素

//*[@title='hoge' and @class!='fuga']
/descendant::*[@title='hoge' and @class!='fuga']

form 要素の 3 番目の input 要素

//form/descendant::input[3]	/descendant::form/descendant::input[3]

5番目以降の p 要素

//p[position() >=5]

チェックされたチェックボックスの親要素

***//input[@checked='checked']/.. //input[@checked='checked']/parent::node()

RSSフィードのURL

//link[@rel="alternate" and @type="application/rss+xml"]/@href

src が 'images/test.gif' の要素

//*[@src='images/test.gif' ]

img タグで src に 文字列 .gif を含む要素

//img[contains(@src, '.gif')]

Firefox xpath アドオン(右クリックで xpath を表示)

https://addons.mozilla.org/en-US/firefox/addon/xpath-checker/

Xpathの書式

http://itref.fc2web.com/xml/xpath.html

Xpath仕様

http://www.w3.org/TR/xpath/

No.723
12/08 14:07

edit

Xpath

はてなダイアリーキーワード自動リンクAPIをPHPで使用する。

はてなダイアリーキーワード自動リンクAPI

http://developer.hatena.ne.jp/ja/documents/keyword/apis/autolink

パラメーター

uri : http://d.hatena.ne.jp/xmlrpc
encoding : utf8
methodName : hatena.setKeywordLink
parameters : 以下を参照
body(string): キーワードを抽出するテキストを指定します。
score(int): 0〜50。キーワードスコアのしきい値を指定します。指定された値よりもスコアが大きいキーワードのみが抽出されます。省略可。
cname(array): キーワードのカテゴリーを指定します。指定があった場合、「一般」と指定されたカテゴリーのキーワードが抽出されます。指定が無かった場合は、全カテゴリーとなります。book,music,movie,web,elec,animal,anime,food,sports,game,comic,hatena,clubが指定可能です。省略可。
a_target(string): アンカー(a)タグのtarget属性値を指定します。省略可。例:_blank
a_class(string): アンカー(a)タグのclass属性値を指定します。省略可。例:keyword
mode(string): 値として lite を指定すると、キーワード自動リンクの結果ではなく、自動リンクに使われるキーワード一覧が返却されます。省略可

PHPソース例

require_once 'XML/RPC.php'; 
$text = "日本語の文化と日本語のテスト";
$out_text = hatena_keyword_link($text);
print_r($out_text);
function hatena_keyword_link( $body ){
	$body = mb_convert_encoding( $body,'utf8',mb_internal_encoding() );
    $params = new XML_RPC_Value(array(
        "body"     => new XML_RPC_Value( $body , "string" ),
        "score"    => new XML_RPC_Value( 0 , "int" ),
        "a_target" => new XML_RPC_Value( '_blank', "string"),
        "a_class"  => new XML_RPC_Value( 'keyword', "string")
        ), "struct");
    $msg = new XML_RPC_Message("hatena.setKeywordLink", array($params));
	$client = new XML_RPC_Client( "/xmlrpc" , "d.hatena.ne.jp", 80 );
    $response = $client->send($msg);
    if (!$response->faultCode()) {
			$val = $response->value();
			$data = XML_RPC_decode($val);
			return $data;
	}
	else {
		return PEAR::raiseError( $response->faultCode(), $response->faultString() );
	}
}

実行結果

<a class="keyword" target="_blank" href="http://d.hatena.ne.jp/keyword/%C6%FC%CB%DC%B8%EC">日本語</a>の<a class="keyword" target="_blank" href="http://d.hatena.ne.jp/keyword/%CA%B8%B2%BD">文化</a>と<a class="keyword" target="_blank" href="http://d.hatena.ne.jp/keyword/%C6%FC%CB%DC%B8%EC">日本語</a>の<a class="keyword" target="_blank" href="http://d.hatena.ne.jp/keyword/%A5%C6%A5%B9%A5%C8">テスト</a> 
No.721
05/02 15:07

edit

API
PEAR

PHPでWEBページをSQLライクに取得する。【htmlSQL】

■ htmlSQL

http://www.jonasjohn.de/lab/htmlsql.htm

使い方は

■ 例

http://codedump.jonasjohn.de/
というサイトの
クラスが "SnippetList" の ul タグを取得する場合
SELECT * FROM ul WHERE $class == "SnippetList"

というSQL文になります。

PHPコードで書くと以下の通り。

その他

htmlSQLのバリエーションとしては

■ ページのタイトルを取得する場合

SELECT text FROM title

<?php
    include_once("../snoopy.class.php");
    include_once("../htmlsql.class.php");
    $wsql = new htmlsql();
    // connect to a URL
    if (!$wsql->connect('url', 'http://codedump.jonasjohn.de/')){
        print 'Error while connecting: ' . $wsql->error;
        exit;
    }
    if (!$wsql->query('SELECT * FROM ul WHERE $class == "SnippetList"')){
        print "Query error: " . $wsql->error; 
        exit;
    }
    // show results:
    foreach($wsql->fetch_array() as $row){
        print_r($row);        
    }
?>

■ htmlSQLを使って取得したデータの日本語が文字化けする場合

htmlsql.class.php のソースの中の 201行目

$this->page = $this->snoopy->results;
$this->page = mb_convert_encoding( $this->page, 'UTF-8', 'AUTO' );	// これを追加

を付け足すことで回避できます。


参考:http://fdays.blogspot.com/2008/04/htmlsql.html


No.717
03/26 14:02

edit

改行コードを(LF)に統一する

PHPで改行コードをLF(¥n)に統一するには

$str = str_replace("\r\n","\n",$str);
$str = str_replace("\r","\n",$str);

とします。

1行で書きたいなら

$str = preg_replace("/\r\n|\r|\n/", "\n", $str);

と書きます。

No.712
01/04 17:41

edit

PHPで & → &amp (htmlエンティティ)に変換し、戻す

変換するには

$text = htmlspecialchars($text);

戻すには

$text = htmlspecialchars_decode($text);


No.709
08/12 10:25

edit

HTMLを取得(スクレイピング)してパース(解析)する

■ snoopy

http://sourceforge.net/projects/snoopy/

おもなメソッド解説

fetch($URI);
HTMLを取得

fetchtext($URI)
テキストのみを取得

fetchform($URI)
フォーム要素 <form>〜</form>のみを取得

fetchlinks($URI)
<a>タグのURIリストを取得

snoopyはどちらかというと、スパイダー(ロボット)に近いのでパーサとしては少し低機能ですが、使い勝手は非常にいいです。

■ simplehtmldom

http://sourceforge.net/projects/simplehtmldom/

require_once "simple_html_dom.php";
$html = file_get_html($url);
foreach($html->find('a') as $element){
	   echo $element->href . '
';
}
No.707
08/06 10:53

edit

Youtube API を使って自分のサイトでYouYube検索を行う

文字列「Michael Jackson」で10件検索

http://gdata.youtube.com/feeds/api/videos?vq=michael+Jackson&max-results=10

ビデオID「MYx3BR2aJA4」の情報を取得する

http://gdata.youtube.com/feeds/api/videos/MYx3BR2aJA4

ビデオID「MYx3BR2aJA4」の関連動画を取得する

http://gdata.youtube.com/feeds/api/videos/MYx3BR2aJA4/related

その他検索方法

http://gdata.youtube.com/feeds/projection/standardfeeds/FEED_ID

FEED_IDに指定できる文字列

feedid	説明
top_rated	評価の高い動画
top_favorites	お気に入り登録の多い動画
most_viewed	再生回数が多い動画
most_discussed	最も議論された動画
most_linked	リンクの多い動画
most_responded	動画レスポンスの多い動画
recently_featured	最近のおすすめ動画
watch_on_mobile	携帯電話のための動画

ユーザ「USER_NAME」のお気に入りに登録されているビデオを取得

http://gdata.youtube.com/feeds/api/users/USER_NAME/favorites

再生リスト「PLAYLIST_ID」のビデオを取得

http://gdata.youtube.com/feeds/projection/playlists/PLAYLIST_ID

ユーザ「USER_NAME」のプロファイルを取得

http://gdata.youtube.com/feeds/projection/users/「USER_NAME」

ユーザ「USER_NAME」が登録している再生リストを取得

http://gdata.youtube.com/feeds/projection/users/USER_NAME/playlists

ユーザ「USER_NAME」の登録チャンネルを取得

http://gdata.youtube.com/feeds/projection/users/USER_NAME/subscriptions

ユーザ「USER_NAME」のユーザコンタクトリストに登録されているユーザを取得

http://gdata.youtube.com/feeds/projection/users/username/contacts

JSOC-Cフォーマット(簡略版JSON)でデータを取得する

後ろに
?v=2&alt=jsonc
を追加する

http://gihyo.jp/dev/feature/01/jquery-ajax/0003

No.706
10/03 19:04

edit

API

PHPのGD画像関数

GD関数で画像の幅、高さを取得

$filename = 'test.jpeg';
$info = getimagesize($filename);
print_r($info);
出力例
        (
            [0] => 160
            [1] => 144
            [2] => 2
            [3] => width="160" height="144"
            [bits] => 8
            [channels] => 3
            [mime] => image/jpeg
        )

test.jpeg を開いて 0,0 の位置のピクセルの色RGB情報を16進数の数値で取得する

$filename = 'test.jpeg';
$jpeg = imagecreatefromjpeg($filename);
$rgb = imagecolorat($jpeg,0,0);
$info = imagecolorsforindex($jpeg,$rgb);
$r = sprintf("%02x",$info['red']);
$g = sprintf("%02x",$info['green']);
$b = sprintf("%02x",$info['blue']);
print "r:{$r}  g:{$g}  b:{$b}  ";

GD および Image 関数

gd_info — 現在インストールされているGDライブラリに関する情報を取得する
getimagesize — 画像の大きさを取得する
image_type_to_extension — 画像形式からファイルの拡張子を取得する
image_type_to_mime_type — getimagesize, exif_read_data, exif_thumbnail, exif_imagetypeから返される 画像形式のMIMEタイプを取得する
image2wbmp — ブラウザまたはファイルにイメージを出力する
imagealphablending — イメージのブレンドモードを設定する
imageantialias — アンチエイリアス機能を使用すべきかどうかを判断する
imagearc — 部分楕円を描画する
imagechar — 水平に文字を描画する
imagecharup — 垂直に文字を描画する
imagecolorallocate — 画像で使用する色を作成する
imagecolorallocatealpha — 画像で使用する色を透過度を指定して作成する
imagecolorat — ピクセルの色のインデックスを取得する
imagecolorclosest — 指定した色に最も近い色のインデックスを取得する
imagecolorclosestalpha — 指定した色+アルファ値に最も近い色のインデックスを取得する
imagecolorclosesthwb — 色合い、白、黒を有する色のインデックスを得る
imagecolordeallocate — イメージの色リソースを開放する
imagecolorexact — 指定した色のインデックスを取得する
imagecolorexactalpha — 指定した色+アルファ値のインデックスを取得する
imagecolormatch — パレットイメージの色を True カラーイメージに近づける
imagecolorresolve — 指定した色または出来るだけ近い色のインデックスを得る
imagecolorresolvealpha — 指定した色+アルファ値または最も近い色のインデックスを取得する
imagecolorset — 指定したパレットインデックスの色を設定する
imagecolorsforindex — カラーインデックスからカラーを取得する
imagecolorstotal — 画像パレットの色数を検出する
imagecolortransparent — 透明色を定義する
imageconvolution — div および offset の係数を使用し、3x3 の畳み込み配列を適用する
imagecopy — 画像の一部をコピーする
imagecopymerge — イメージの一部をコピー、マージする
imagecopymergegray — グレースケールでイメージの一部をコピー、マージする
imagecopyresampled — 再サンプリングを行いイメージの一部をコピー、伸縮する
imagecopyresized — 画像の一部をコピーしサイズを変更する
imagecreate — パレットを使用する新規画像を作成する
imagecreatefromgd2 — GD2 ファイルまたは URL から新規イメージを生成する
imagecreatefromgd2part — GD2 ファイルまたは URL の指定した部分から新規イメージを生成する
imagecreatefromgd — GD ファイルまたは URL から新規イメージを生成する
imagecreatefromgif — ファイルまたは URL から新規画像を作成する
imagecreatefromjpeg — ファイル又は URL から新規 JPEG 画像を作成する
imagecreatefrompng — ファイルまたは URL から新規 PNG 画像を作成する
imagecreatefromstring — 文字列の中のイメージストリームから新規イメージを作成する
imagecreatefromwbmp — ファイルまたは URL から新規イメージを作成する
imagecreatefromxbm — ファイル又は URL から新規イメージを生成する
imagecreatefromxpm — ファイルまたは URL から新規イメージを生成する
imagecreatetruecolor — TrueColor イメージを新規に作成する
imagedashedline — 破線を描画する
imagedestroy — 画像を破棄する
imageellipse — 楕円を描画する
imagefill — 塗り潰す
imagefilledarc — 楕円弧を描画し、塗りつぶす
imagefilledellipse — 塗りつぶされた楕円を描画する
imagefilledpolygon — 塗りつぶした多角形を描画する
imagefilledrectangle — 塗りつぶした矩形を描画する
imagefilltoborder — 特定色で塗りつぶす
imagefilter — 画像にフィルタを適用する
imagefontheight — フォントの高さを取得する
imagefontwidth — フォントの幅を取得する
imageftbbox — freetype2 によるフォントを用いたテキストを囲む箱を取得する
imagefttext — FreeType 2 によるフォントを用いてイメージにテキストを描画する
imagegammacorrect — GD イメージにガンマ補正を適用する
imagegd2 — GD2 イメージをブラウザまたはファイルに出力する
imagegd — GD イメージをブラウザまたはファイルに出力する
imagegif — ブラウザまたはファイルへ画像を出力する
imagegrabscreen — 画面全体をキャプチャする
imagegrabwindow — ウィンドウをキャプチャする
imageinterlace — インターレースを有効もしくは無効にする
imageistruecolor — 画像が truecolor かどうか調べる
imagejpeg — 画像をブラウザまたはファイルに出力する
imagelayereffect — アルファブレンディングフラグを設定し、 libgd にバンドルされているレイヤ効果を使用する
imageline — 直線を描画する
imageloadfont — 新しいフォントを読み込む
imagepalettecopy — あるイメージから他のイメージにパレットをコピーする
imagepng — PNG イメージをブラウザまたはファイルに出力する
imagepolygon — 多角形を描画する
imagepsbbox — PostScript Type1 フォントを用いてテキスト矩形のバウンディングボックスを指定する
imagepsencodefont — フォントの文字エンコードベクトルを変更する
imagepsextendfont — フォントを展開または圧縮する
imagepsfreefont — PostScript Type 1 フォント用メモリを解放する
imagepsloadfont — ファイルから PostScript Type 1 フォントをロードする
imagepsslantfont — フォントを傾ける
imagepstext — PostScript Type1 フォントを用いて画像の上に文字列を描く
imagerectangle — 矩形を描画する
imagerotate — 指定された角度で画像を回転する
imagesavealpha — PNG 画像を保存する際に(単一色の透過設定ではない)完全な アルファチャネル情報を保存するフラグを設定する
imagesetbrush — 線の描画用にブラシイメージを設定する
imagesetpixel — 点を生成する
imagesetstyle — 線描画用のスタイルを設定する
imagesetthickness — 線描画用の線幅を設定する
imagesettile — 塗りつぶし用のイメージを設定する
imagestring — 文字列を水平に描画する
imagestringup — 文字列を垂直に描画する
imagesx — 画像の幅を取得する
imagesy — 画像の高さを取得する
imagetruecolortopalette — TrueColor イメージをパレットイメージに変換する
imagettfbbox — TypeType フォントを使用したテキストの bounding box を生成する
imagettftext — TrueType フォントを使用してテキストを画像に書き込む
imagetypes — この PHP がサポートしている画像形式を返す
imagewbmp — ブラウザまたはファイルにイメージを出力する
imagexbm — XBM 画像をブラウザあるいはファイルに出力する
iptcembed — バイナリ IPTC データを JPEG イメージに埋めこむ
iptcparse — バイナリの IPTC ブロックのタグをパースする
jpeg2wbmp — JPEG イメージファイルから WBMP イメージファイルに変換する
png2wbmp — PNG イメージファイルから WBMP イメージファイルに変換する
No.705
10/19 10:47

edit

画像

htmlページを取得、解析してページタイトルを得る

PHPでhtmlページのタイトルタグ(任意のタグの内容でも可能)を取得するには。

function _get_element( $pElement, $pSource ) {
   $_data = null;
   $pElement = strtolower( $pElement );
   $_start = strpos( strtolower( $pSource ), chr(60) . $pElement, 0 );
   $_start = strpos( $pSource, chr(62), $_start ) + 1;
   $_stop = strpos( strtolower( $pSource ), "</" . $pElement .    chr(62), $_start );
   if( $_start > strlen( $pElement ) && $_stop > $_start ) {
      $_data = trim( substr( $pSource, $_start, $_stop - $_start ) );
   }
   return( $_data );
}

function _get_page_title( $url ) {
    $html = file_get_contents($url);
    $html = mb_convert_encoding( $html, 'UTF-8', 'AUTO' );
    $title = $this->_get_element( 'title', $html );
    $html = mb_convert_encoding($html, mb_internal_encoding(), "auto" );
    if ( $title ) {
        return $title;
    }
    else {
        return 'non-title';
    }
}

として

$url = 'http://www.yahoo.co.jp/';
$title = $this->_get_page_title( $url );

とします。

http://d.hatena.ne.jp/steel-plate/20080417/1208445174


No.704
11/02 14:03

edit

PHP(Smartyプラグイン)ではてな記法を使用する

PHP用はてな記法パーサをインストール

http://d.hatena.ne.jp/anatoo/20090608/1244387241

サーバのコマンドライン(シェル)から

pear channel-discover openpear.org
pear install openpear/HatenaSyntax-beta

でインストール完了。(要PHPバージョン > 5.25 )

また PEARのバージョンが 1.8.0 より低い場合もインストールできないので、アップデートします

yum update php-pear
pear upgrade PEAR

Smartyのプラグインフォルダに modifier.hatena_syntax.php というファイル名を作成して

下記の内容をコピー

<?php
require_once('HatenaSyntax.php');
function smarty_modifier_hatena_syntax($string){
	return HatenaSyntax::render($string);
}
?>

テンプレートファイルに

{$text|hatena_syntax}

などと書けばはてな記法が使えます。

No.693
04/07 13:45

edit

PEAR

PHPのファイルアップロードのファイル要領制限(upload_max_filesize)を変更する。

PHPのファイルアップロードのファイル要領制限を変更するには次の3つのパラメーターを調整する必要があります。 (必ずしも3つの値を揃える必要はありません)

upload_max_filesize = 256M
post_max_size = 256M
memory_limit = 256M

● 1. php.ini 内に記述する場合

upload_max_filesize = 256M
post_max_size = 256M
memory_limit = 256M

● 2. .htaccess に記述する場合

#  ファイルアップロードの最大サイズを 10Mに設定
php_value upload_max_filesize 10M
php_value post_max_size  10M
#  ファイルアップロードの最大サイズを 500Kに設定
php_value upload_max_filesize 500K
php_value post_max_size 500K

● 3. phpスクリプト内に記述する場合(サーバの設定によっては許可されていない場合があります)

// ファイルアップロードの最大サイズを 10M に設定
ini_set('upload_max_filesize', 10 * 1024 * 1024); 

● なお現在のファイルアップロード制限の設定を取得するには

print "upload_max_filesize: " . ini_get('upload_max_filesize')." Bytes です。";

とします。

No.690
06/03 11:00

edit

ファイル
.htaccess
メモリ
エラー対処

SmartyプラグインでOSとブラウザ判別を行う

ファイル名 modifier.is_ua_with_osmb.php で下記コードを保存し Smartyの plugin フォルダに入れます。

<?php
// Version 1.2
function smarty_modifier_is_ua_with_osmb($arg,$debug=false){
	$useos; $browser; $os_browser;
	if (  preg_match('/Mac/',$_SERVER['HTTP_USER_AGENT']) ){ $useos='mac'; }
	elseif (  preg_match('/Win/',$_SERVER['HTTP_USER_AGENT']) ){ $useos='win'; }
	else { $useos = 'other'; }
	if ( preg_match('/Opera/',$_SERVER['HTTP_USER_AGENT']) && preg_match('/Version\/([0-9]+)/',$_SERVER['HTTP_USER_AGENT'], $r) ){ $browser = 'opera'.$r[1]; }
	elseif ( preg_match('/MSIE ([0-9])+/',$_SERVER['HTTP_USER_AGENT'], $r) ){ $browser = 'ie'.$r[1]; }
	elseif ( preg_match('/Safari/',$_SERVER['HTTP_USER_AGENT']) && preg_match('/Version\/([0-9]+)/',$_SERVER['HTTP_USER_AGENT'], $r) ){ $browser = 'safari'.$r[1]; }
	elseif ( preg_match('/Chrome\/([0-9]+)/',$_SERVER['HTTP_USER_AGENT'],$r) ){ $browser = 'chrome'.$r[1]; }
	elseif ( preg_match('/Firefox\/([0-9]+)/',$_SERVER['HTTP_USER_AGENT'], $r) ){ $browser = 'firefox'.$r[1]; }
	elseif ( preg_match('/Gecko/',$_SERVER['HTTP_USER_AGENT']) ){ $browser = 'gecko'; }
	else{ $browser = $_SERVER['HTTP_USER_AGENT']; }
	$os_browser = $useos.'_'.$browser;
	if ($debug){
		return "{$os_browser} : {$_SERVER['HTTP_USER_AGENT']}";
	}
	else{
		if ( strcmp($arg, $os_browser)==0 ){ return true; }
		else{ return false; }
	}
}
?>

■ 使い方

// デバッグモード
{ ""|is_ua_with_osmb:debug }
// 例
{ if "mac_safari4"|is_ua_with_osmb }このブラウザは mac版safari4です
{ elseif "win_ie8"|is_ua_with_osmb }このブラウザは win版IE8です
{ elseif "win_firefox3"|is_ua_with_osmb }このブラウザは win版firefox3です
{ else }それ以外のブラウザです
{ /if }

まず先頭に OSの種類を記述し、アンダースコアでブラウザとメジャーバージョンを記述します。

(記述は全て小文字)

No.674
03/23 13:23

edit

Smarty

PHPプログラムが使用しているメモリを取得する

PHPプログラムが使用しているメモリを取得するには

$mem = memory_get_usage();
$mem = number_format($mem);
print("Memory:{$mem}");

などとするとよいでしょう。

※ ただし関数を呼び出した時点での使用メモリなので注意。


最大どれだけメモリを使用したかは

memory_get_peak_usage();

で取得できます

メソッドとして持っておくといいでしょう

public function dumpmem()
{
	print "\n".'<pre style="text-align:left;">'."\n";
	$mem     = number_format(memory_get_usage());
	$peakmem = number_format(memory_get_peak_usage());
	print("Memory:{$mem} / Peak Memory:{$peakmem}");
	print "\n</pre>\n";
}

No.653
03/12 17:34

edit

メモリ

Smarty の プラグインへの引数指定方法

通常( $data を myplugin に渡す )

{$data|myplugin}

引数を2つ($data1, $data2)渡す

{$data1|myplugin:$data2}

引数を3つ($data1, $data2, $data3)渡す

{$data1|myplugin:$data2:$data3}

配列や連想配列($ar_data)を引数として渡す

{$ar_data|@myplugin}

No.649
09/15 14:01

edit

Smarty
配列

配列(の配列)の文字コードを一括変換する

http://d.hatena.ne.jp/seto-san/20081203/1228274418

にありました。

以下引用。(クラスメソッドとして記述してあるので、通常の関数として使用したい場合は)

$target[$key] = $this->_mbConvertEncodingEx($val,$toEncoding,$fromEncoding);
↓
$target[$key] = _mbConvertEncodingEx($val,$toEncoding,$fromEncoding);

とするとよいでしょう。

/**
 * mb_convert_encoding()の拡張
 *
 * @param  mixed  $target       arrayかstring
 * @param  string $toEncoding   エンコード先
 * @param  string $fromEncoding エンコード元(default:null)
 * @return mixed  arrayが来たらarrayを、stringが来たらstringを
 */
function _mbConvertEncodingEx($target, $toEncoding, $fromEncoding = null)
{
  if (is_array($target)) {
    foreach ($target as $key => $val) {
      if (is_null($fromEncoding)) {
        $fromEncoding = mb_detect_encoding($val);
      }
      $target[$key] = $this->_mbConvertEncodingEx($val,$toEncoding,$fromEncoding);
    }
  } else {
    if  (is_null($fromEncoding)) {
      $fromEncoding = mb_detect_encoding($target);
    }
    $target = mb_convert_encoding($target, $toEncoding,$fromEncoding);
  }
  return $target;
}

No.648
11/12 11:21

edit

配列

ZIP Archive のインストール

ZIPファイルを扱う pecl拡張をインストールする。

root になって

yum install php-devel
yum install zlib-devel
pecl install zip

でインストール完了。

完了すると

You should add "extension=zip.so" to php.ini

と表示されるので

/etc/php.ini に【extension=zip.so】を追加。

apacheの再起動をします

apachectl graceful

確認は phpinfo() で出来ます。

pecl拡張がインストールできない環境の場合

http://phpspot.org/blog/archives/2007/10/phpzip.html


■ phpmyadmin(GPLライセンス)のライブラリを使用する

http://winofsql.jp/VA003334/phpVarious060803234456.htm

No.640
11/04 14:58

edit

ファイル

PHP文字コード, HTMLのヘッダのエンコード指定が正しいのに何故か時々文字化けする不具合の対応

なぜか時々文字化けが起きる。。。といった不具合の時は

PHPの最初の方に記述

$encoding = 'UTF-8';     // もしくは EUC-JP  ,  SJIS
ini_set('mbstring.internal_encoding', $encoding );
ini_set('mbstring.script_encoding', $encoding );
ini_set('default_charset', $encoding );

これでなおることがあります。

こちらの方法でも直ることがあります(サーバによる)

.htaccess に下記の記述をしてサーバにアップロード

php_value mbstring.internal_encoding EUC-JP
php_value mbstring.script_encoding EUC-JP
php_value default_charset EUC-JP

参考:http://blog.factree.co.uk/memo/000028.html

No.634
01/08 14:44

edit

日本語
.htaccess

出力バッファをフラッシュして出力と同時に画面に表示させる

PHPでは標準で出力バッファがonになっています。

これを制御して出力があったと同時に画面に表示させるには

for ($i=0 ; $i<10 ; $i++){
	print $i;
	flush();
	sleep(5);
}

という風にします。

No.617
08/11 11:40

edit

PHPであるディレクトリ(フォルダ)内のファイルを全て削除する

PHPであるディレクトリ(フォルダ)内のファイルを全て削除するには

function delete_allfile($dirpath=''){
	if ( strcmp($dirpath,'')==0 ){ die('delete_allfile : error : please set dir_name'); }
	$deleted_list = array();
	$dir = dir($dirpath);
	while ( ($file=$dir->read()) !== FALSE ){
		if (preg_match('/^\./',$file)){ continue; }	// skip dir , skip hidden file
		else {
			array_push($deleted_list, $file);
			if ( ! unlink("$dirpath/$file") ){ die("delete_allfile : error : can not delete file [{$dirpath}/{$file}]"); }
		}
	}
	return $deleted_list;
}
$deleted_list  = delete_allfile(ディレクトリ名);

で実行

No.608
07/03 11:56

edit

ファイル

PHPで1秒以下の短い時間(ミリ秒) sleep させる

何度も調べてしまうのでメモ

0.5秒スリープさせるには
usleep(500000);
1秒スリープさせるには
usleep(1000000);

と記述します。

No.607
02/19 10:50

edit

Smartyで配列の最初と最後の要素を検知する

Smartyで配列の最初、最後を検知するには ループ名(任意)をつけて

.first

.last

で知ることが出来ます。

{ foreach from=$test_loop key="k" item="v" name="loopname"}
{ if $smarty.foreach.loopname.first }(最初の要素){$v.name}です。{ /if }
{ $v.name }です。
{ if $smarty.foreach.loopname.last }(最後の要素){$v.name}です。{ /if }
{ /foreach }

ちなみに配列の長さは @count で求めることが出来ます

{$test_loop|@count}
No.601
11/01 11:18

edit

Smarty
配列

900 * (1.1) =990 を小数点第一位で切り上げると答えは 991 になる

PHP でも Perl でもいいのですが以下のような計算を小数点第一位で切り上げると、我々人間が予想した数値と違う結果になります。

■ PHP

$a = 900 * (1.1);
print $a."\n";

$b   = ceil( $a );
print $b."\n";

■ Perl

use POSIX;
my $a = 900 * (1.1);
print $a."\n";

my $b   = ceil( $a );
print $b."\n";

いずれも答えは

990
991

となります。

PHPマニュアル:http://manual.xwd.jp/language.types.float.html

によると

0.1 や 0.7 のような簡単な小数表現も、若干精度を失うことなく内部的な 2 進表現に変換することはできません。 これにより、混乱する結果を生じることがあります。 つまり floor((0.1+0.7)*10) は、 予想される 8の代わりに実際の内部表現の結果として 7.9999999999... のようなものを結果として返します。

これは、有限の桁数の小数点表記で正確に表現できない分数が存在するという事実に関係しています。 例えば、1/3 の小数表記は 0.3333333. . . となります。

よって、小数の最後の桁を信用してはいけませんし、 小数が等しいという比較を行ってはいけません。より高い精度が必要な場合には、 任意精度数学関数または gmp 関数を代わりに使用してください。

との事。

● bc math を使用する

先ほどの計算は bc math 関数を使って 次のように書き換えることができます。

$a = bcmul( 900 , 1.1 , 99);
echo $a;
echo ceil($a);

● be math 関数

bcadd — 2つの任意精度の数値を加算する
bccomp — 2 つの任意精度数値を比較する
bcdiv — 2つの任意精度数値で除算を行う
bcmod — 2 つの任意精度数値の剰余を取得する
bcmul — 2つの任意精度数値の乗算を行う
bcpow — 任意精度数値をべき乗する
bcpowmod — 任意精度数値のべき乗の、指定した数値による剰余
bcscale — すべての BC 演算関数におけるデフォルトのスケールを設定/取得する
bcsqrt — 任意精度数値の平方根を取得する
bcsub — 任意精度数値の減算を行う
No.587
04/19 18:02

edit

Smarty でテンプレート側で配列の長さ(要素数)を求める

Smartyはテンプレート内でPHP標準関数が使用できます。

なので

配列 $loop の要素数を知るには

{$loop|@count}

でOKです


if文で使用するには

{ if count($loop) > 0 }要素数は1以上です{/if}

計算式で使用するには( 例:$loopの要素数に2を足す )

{ math equation=a+b a=$loop|@count b=2 assign=kekka }
{$kekka}

No.583
01/21 11:11

edit

配列
Smarty

Smartyテンプレート内で変数に代入をする、計算をする

まずテンプレート内での変数の定義

{assign var="hogehoge" value="test_txt" }
{assign var="aaa" value="999" }
{assign var="bbb" value="10000" }

{ math equation=a+b a=$aaa b=$bbb assign=kekka }

{$kekka}には10999という値が入ります


◆ 文字列を連結して代入する場合

$year = '2001';

$month = '01';

$date = '15';

{ assign var="now_date" value="`$v.year`/`$v.month`/`$v.date`" }
変数をバッククォートで囲むと文字列と混ぜることが出来ます。
No.580
10/14 23:47

edit

Smarty

No.575
06/10 15:32

edit

連想配列から配列の値を削除する

phpの連想配列(ハッシュ)で

$hash=array(
 'aa' => 'aiueo' ,
 'bb' => 'kakikukeko' ,
 'cc' => 'sasisuseso' ,
);

という配列から $hash['bb'] のキーと値を削除するには

unset($hash['bb']);

とします。

※ なおこれは普通の配列には使用しない方がいいです。(削除した配列は「欠番」となりますので、それより後ろのメンバがつまるわけではないため)

普通の配列には array_splice() を使用しましょう。

array_splice ( array &$input , int $offset [, int $length [, mixed $replacement = array() ]] )

配列 input から offset および length で指定された要素を削除し、配列 replacement でそれを置換します

※ 普通の配列の「欠番」をつめる array_values() というのもあります(パフォーマンスをあまり気にしない局面では使えると思います)

$list = array_values($list);
No.545
06/25 18:08

edit

配列

PHPでファイル名からパス名、ファイル名、拡張子を調べる。また拡張子を取り除く

意外と何度も調べてしまうのでメモ

● ファイル名から拡張子を調べる

echo pathinfo('./aaa/bbb/ccc/ddd.jpg', PATHINFO_EXTENSION);

結果

jpg

● ファイル名からパス名(ディレクトリ名)を調べる

echo pathinfo('./aaa/bbb/ccc/ddd.jpg', PATHINFO_DIRNAME);

結果

./aaa/bbb/ccc

● パス・ファイル名からパス名(ディレクトリ名)を取り除いたファイル名を調べる

echo pathinfo('./aaa/bbb/ccc/ddd.jpg', PATHINFO_BASENAME);

結果

ddd.jpg

● ファイル名から「ディレクトリ名・拡張子」を取り除いたファイル名を調べる

echo pathinfo('./aaa/bbb/ccc/ddd.jpg', PATHINFO_FILENAME);

結果

ddd

● pathinfo 関数(ファイル名からパス名、ファイル名、拡張子を調べる関数)

$p = pathinfo('./aaa/bbb/ccc/ddd.jpg');
print_r($p);

// 実行結果

Array
(
    [dirname] => ./aaa/bbb/ccc
    [basename] => ddd.jpg
    [extension] => jpg
    [filename] => ddd
)

ただし、拡張子がないときは $p['extension'] がセットされて帰ってこないので注意。

● PHPでファイル名から拡張子を取り除くには

● 1. 拡張子がわかっている場合

basename ("ファイル名","サフィックス");

とします。

$test=basename ( "hogehoge.jpg",".jpg" );

● 2.拡張子がわかってない場合

関数を定義するのがいいでしょう(か?)

function _delete_extention( $string='' ){
$p = pathinfo($string);
return basename ( $string, ".{$p['extension']}" );
}
No.528
04/03 17:01

edit

ファイル

PHPで文字列を比較するときに == は絶対に使ってはいけない。

PHPで文字列を比較するときに == は絶対に使ってはいけない。

というのを意外とみなさん知らないようで、改めてここに記述しておきます。

参考:がるの健忘録 - 素晴らしき自動的な世界〜或いは「型のない」世界〜

参考:がるの健忘録

参考:zuzara : PHPの比較演算子($a == $b)で注意が必要なとき

参考:PHPの文字列比較で気をつけるべきこと - 暗黙の型変換 - EC studio 技術ブログ

Perlだと文字列比較は

if ( $a eq $b ){ print '同じです'; }

PHPだと

if ( strcmp($a,$b)==0 ){ print '同じです'; }

と書くのがいいでしょう。

また

if ( $a===$b ){ print '同じです'; }

と(===による厳密な比較)も有効でしょう。↓こちらは要チェックです

PHP 型の比較表

No.506
03/16 14:01

edit

PHPで相対パスから絶対URL(URI)を作成する。または絶対パスを返す。

元となるURLとそれに対する相対パスを指定すると絶対URLを作成する関数です。

元URL:http://www.test.com/gallery/index.html
相対パス:../contact.html
URL:http://www.test.com/contact.html

使い方

$url = make_uri('元url','相対パス');

です。

関数 make_uri

//================ make_uri:version 1.4
function make_uri($base='', $rel_path=''){
    $base = preg_replace('/\/[^\/]+$/','/',$base);
    $parse = parse_url($base);
    if (preg_match('/^https\:\/\//',$rel_path) ){
        return $rel_path;
    }
    elseif ( preg_match('/^\/.+/', $rel_path) ){
        $out = $parse['scheme'].'://'.$parse['host'].$rel_path;
        return $out;
    }
    $tmp = array();
    $a = array();
    $b = array();
    $tmp = preg_split("/\//",$parse['path']);
    foreach ($tmp as $v){
        if ($v){  array_push($a,$v); }
    }
    $b = preg_split("/\//",$rel_path);
    foreach ($b as $v){
        if ( strcmp($v,'')==0 ){ continue; }
        elseif ($v=='.'){}
        elseif($v=='..'){ array_pop($a); }
        else{ array_push($a,$v); }
    }
    $path = join('/',$a);
    $out = $parse['scheme'].'://'.$parse['host'].'/'.$path;
    return $out;
}

元URLと相対パスから絶対パス(ドキュメントルートからのパス表記)を返す関数( make_apath )はこちら。

//============= make_apath:version 1.1
function make_apath($base='', $rel_path=''){
	$base = preg_replace('/\/[^\/]+$/','/',$base);
	$parse = parse_url($base);
	if (preg_match('/^https\:\/\//',$rel_path) ){
		return $rel_path;
	}
	elseif ( preg_match('/^\/.+/', $rel_path) ){
		$out = $parse['scheme'].'://'.$parse['host'].$rel_path;
		return $out;
	}
	$tmp = array();
	$a = array();
	$b = array();
	$tmp = preg_split("/\//",$parse['path']);
	foreach ($tmp as $v){
		if ($v){  array_push($a,$v); }
	}
	$b = preg_split("/\//",$rel_path);
	foreach ($b as $v){
		if ( strcmp($v,'')==0 ){ continue; }
		elseif ($v=='.'){}
		elseif($v=='..'){ array_pop($a); }
		else{ array_push($a,$v); }
	}
	$path = join('/',$a);
	return '/'.$path;
}
No.501
01/21 11:58

edit

URL

phpでjsonを扱う / json_decode() / json_encode()

php 7.3 以降の場合は 4番目の引数に JSON_THROW_ON_ERROR を渡すと デコードエラーの時にエラーをスローしてくれます

$data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);

● 読みやすい形でphpの配列をjsonに変換する(エンコード)

日本語をutf-8エンコード(一見文字化けのように見える)したくない場合は必ず JSON_UNESCAPED_UNICODE をつけましょう

$json = json_encode( $array, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT );
if (json_last_error() !== JSON_ERROR_NONE) {
    die( "JSON DECODE ERROR in FILE-NAME.json" );
}

● jsonデータをphpの配列にする(デコード)

$array = json_decode( $json, true );
if (json_last_error() !== JSON_ERROR_NONE) {
    die( "JSON DECODE ERROR in FILE-NAME.json" );
}

● phpの配列をjson形式にする(エンコード)

$json = json_encode( $array );
if (json_last_error() !== JSON_ERROR_NONE) {
    die( "JSON DECODE ERROR in FILE-NAME.json" );
}

● php5.2より低いバージョンでjsonを扱う 「php-jsonのインストール」

PHPのバージョンが 5.2より低いphpでjsonを扱うには 「php-json」をインストールします。 (ヘテムルなど大手レンタルサーバ会社のサーバには標準でインストールされています。) (他にも PEARパッケージなどがありますが、phpエクステンションとして提供されているphp-json の方が高速なので、php-json を使用します。)

1. phpバージョンの確認

php --version

PHPのバージョンが 5.2.0 以上の場合、php-json はあらかじめインストールされています。 それより低いバージョンの場合のみ手動でインストールしましょう。

2. json-phpのインストール

yum install php-json

でOKです。

4. json.soを指定のディレクトリ(/usr/lib/php/modules/)に移動

cp json.so /usr/lib/php/modules/json.so

5. /etc/php.d/json.ini ファイルの作成

'/etc/php.d/json.ini' というファイルを下記の内容で作成します。

   ; Enable json extension module
    extension=json.so

6. apacheの再起動

    apachectl graceful

これでOKです。

7. 確認

php.info(); 関数で確認します。 実行して表示される画面に json の項目とバージョンが正しく表示されていればOK。

8. json関数の使用。

これで関数

json_encode();
json_decode()

が使用できるようになります。

9 json関数使用の注意

$my_array = json_decode($json,true);

json_decode を使用する際は、2つめの引数に true を渡します。 (trueとすると結果が連想配列で帰ってきます。渡さないとオブジェクトで帰ります。)

No.500
02/27 11:44

edit

Smartyでセッション変数、cookie、環境変数を参照する

Smartyテンプレート内でセッション変数、cookie、環境変数の値を参照したいときは下記のようにします。

phpのセッション変数"id"の値を表示

{$smarty.session.id}

クッキーに登録された"username"の値を表示

{$smarty.cookies.username}

環境変数"PATH"の値を表示

{$smarty.env.PATH}

環境変数 "SERVER_NAME" の値を表示

{$smarty.server.SERVER_NAME}

環境変数 "HTTP_USER_AGENT" の値を表示

{$smarty.server.HTTP_USER_AGENT}

■ ただし Smartyで全ての環境変数が取得できるわけではありません。

なので

{ foreach from=$smarty.server key="k" item="v" }
{$k}:{$v} 
{ /foreach }

としてどういう環境変数が取得できるのかを調べるのがいいでしょう。



No.490
04/21 10:18

edit

Smarty
Cookie
セッション

携帯サイトなどCookieを使えないクライアントの場合に自動でセッション変数をURIに埋め込む

(一部の)携帯などでcookieを使えない場合にセッションIDをURIに埋め込んで使用する方法が一般的です。

そこで

・cookieを受け付けるときはcookieを使用したセッション。

・cookieを受け付けないときはURI埋め込みを使用したセッション。

を実現します。

php.ini の設定

session.use_cookies = 1
session.use_only_cookies = 0

としてapache をリスタート

apachectl graceful

で準備OK。

後はPHPスクリプト内で

定数SID が存在するブラウザの場合 → cookie使用不可(携帯など)

定数SID が存在しないブラウザの場合 → 通常のWEBブラウザ

で判別できます。

session_start();
if (SID){
	// cookieを使えないブラウザの処理
}
else {
	// cookieを使えるブラウザの処理
}

No.489
04/21 10:18

edit

携帯スマホサイト
Cookie
セッション

PHPのソースコードを整形する PHP_Beautifier を試す。

PHPコード整形ツール PHP_Beautifier を試してみます。

http://pear.php.net/package/PHP_Beautifier

PHP_Beautifierのインストール

ソースコードを取得してきて PEAR コマンドでインストールする

wget http://pear.php.net/get/PHP_Beautifier-0.1.15.tgz

pear install PHP_Beautifier-0.1.15.tar

でインストール

■ php_beautifier の実行(コマンドライン編)

まずヘルプを表示するには

php_beautifier --help

ソースコードbefore.phpを整形してafter.phpに出力するには

php_beautifier  before.php > after.php

■ php_beautifier の実行(PHPソース編)

$in に入っているPHPソースコードを整形します

require_once 'PHP/Beautifier.php';
$ob = new PHP_Beautifier();
$ob->setInputString( $in );
$ob->process();
$out = $ob->get();
print ($out);

マニュアル:http://beautifyphp.sourceforge.net/docs/

No.488
02/10 18:05

edit

PEAR

Smartyで for文 (for i=0 ; i<10; i++)のような繰り返しを行う。

Smartyでfor文のような繰り返し処理をするには以下のように記述する。

{section name=i start=0 loop=10}
繰り返し回数は{$smarty.section.i.index}です。

$i に変数を代入する場合は下記のように行う
{assign var="i" value=$smarty.section.i.index }
繰り返し回数は{$i}です。

{/section}

No.486
12/22 14:22

edit

Smarty

cookieを使わずにセッション管理する(ログイン認証が必要な携帯サイト用)

セッションは通常cookieを通してやりとりしますが、cookieを使えないブラウザ

(携帯端末 Docomo Softbank )等でセッション機能を実現させたい場合はセッションIDを

URIに埋め込んで使用することになります。

■ セッションをURLに埋め込んで使用するには以下の記述を行います。

/etc/php.iniに設定する場合(書き換えたら apache をリスタート)

session.use_trans_sid = 1

.htaccessに設定する場合

php_flag session.use_trans_sid On

phpコードに記述する場合

ini_set('session.use_trans_sid', '1');

ただし

注意: 相対URLでないURLは外部サイトを指していると仮定され、SIDが追加 されません。これは、SIDを外部のサーバに開示することはセキュリティ 上のリスクとなる可能性があるためです。

なので注意


■ セッションに関するパラメータを変更するには phpコード内に以下の記述を行います。

が、通常書き換えなくてもOKです。

//一文字あたりのビット数(4,5,6)数値が大きいほどセッションIDを短くすることが出来る
ini_set('session.hash_bits_per_character', 6);
//セッションパラメーター名 デフォルト値:PHPSESSID
ini_set('session.name', '_SESSID');
//ハッシュ関数 0:MD5(128bits) 1:SHA(160bit) デフォルト値:0
ini_set('session.hash_function', 1);

参考:

http://labs.scyphus.co.jp/memos/php/session

http://www.yc.musashi-tech.ac.jp/~yamada/doc/php/0802.html

http://ke-tai.org/blog/2007/12/12/php_session_new/

No.481
07/14 14:08

edit

携帯スマホサイト
Cookie
セッション
.htaccess

文字列に「ひらがな(全角)」「漢字(全角)」「カタカナ(全角)」「カタカナ(半角)」が使われているか判別する。

文字列に「ひらがな(全角)」「漢字(全角)」「カタカナ(全角)」が使われているかを判別するには次のようにする

PHP5 + UTF-8の場合

mb_regex_encoding('UTF-8');
if ( preg_match('/[一-龠]+/u', $q)  ){ 漢字を含む時の処理 }
if ( preg_match('/[ァ-ヶー]+/u', $q) ){ カタカナを含む時の処理 }
if ( preg_match('/[ぁ-ん]+/u', $q) ){ ひらがなを含む時の処理 }
if ( preg_match('/[ア-ン゙゚]+/u', $q) ){ 半角カタカナを含む時の処理 }

■ 注意1

正規表現のオプション【 /u 】というのが最後にくっついていますが、

これは文字コード UTF-8 で検索を行うときには必ず必要なものです。

忘れないよう注意!


■ 注意2

また上記の例だと「ー」はひらがなとしてマッチしません。

ひらがなにも「ー」を含ませる場合は

if ( preg_match('/[ー-ん]+/u', $q) ){ ひらがなを含む }



仕方なく mb_ereg で実装する場合は下記の通り

mb_regex_encoding('EUC-JP');

if ( mb_ereg('[一-龠]+', $q) ) { 漢字を含む }


Unicode対応 文字コード表

!JP 付録4 日本語文字一覧

http://jprs.jp/doc/rule/saisoku-1-wideusejp-furoku-4.html


ASCII文字コード一覧表

http://www.psl.ne.jp/perl/pdojo00b.html


memo.xight.org - PHPの文字化け - 5つの誤解と5つの対策

http://memo.xight.org/2007-02-14-1



No.473
11/19 14:06

edit

正規表現
日本語

メモリエラー「PHP Fatal error: Allowed memory size of 8388608 bytes exhausted」

サイズの大きな画像やCSVを加工中にメモリエラー PHP Fatal error: Allowed memory size of 8388608 bytes exhausted が発生することがあります。

このエラーはメモリ不足なので、PHPの最大使用メモリを増やしてあげると回避できます。 下記の例では200MBytesに設定しています。

● 対処法 1.

/etc/php.ini の設定を以下のように変える

memory_limit = 500M      ; Maximum amount of memory a script may consume (8MB)

ギガバイト表記も使えます (4ギガにしたい場合)

memory_limit = 4G      ; Maximum amount of memory a script may consume (8MB)

● 対処法 2.

PHPプログラム内に下記コードを記述する

ini_set('memory_limit', '200M');
No.472
07/02 08:55

edit

ファイル
メモリ

PHPでファイルの移動を行う

● rename関数

rename( $from, $to ) or die("can not move:{$from}:{$to}");

または次のように関数を作ってもいいですか少々遅いと思います。

function move( $from, $to ){
    if ( copy ($from, $to) ){
        unlink($from);
        return true;
    } else{
        return false;
    }
}
No.460
06/16 19:34

edit

ファイル

配列を自然順アルゴリズムでソートを行う【natsort】【natcasesort】

普通にソートすると

 img1.png
 img2.png
 img10.png
 img12.png

となってしまう配列を

img1.png
img10.png
img12.png
img2.png

でソートするのが自然順アルゴリズムによるソート(人間が認識しやすいソート)

これは

$arr=new array(
'img2.png',
'img12.png',
'img1.png',
'img10.png'
);
natsort($arr);

で実行できます。

natsort(配列):自然順アルゴリズムによるソート
natcasesort(配列):自然順アルゴリズムによるソート(大文字小文字の違いを無視)
No.453
11/12 11:23

edit

配列

PHPでソースコードを色づけして表示するライブラリ

● GeSHi - Generic Syntax Highlighter

http://qbnz.com/highlighter/index.php

対応プログラミング言語

Actionscript、ADA、Apache Log、AppleScript、ASM、ASP、AutoIT、Backus-Naur form、Bash、BlitzBasic、C、C for Macs、C#、C++、CAD DCL、CadLisp、CFDG、CFDG、ColdFusion、CSS、Delphi、DIV、DOS、Eiffel、Fortran、Fortran、FreeBasic、GML、Groovy、HTML、Inno、IO、Java、Java 5、Javascript、LaTeX、Lisp、Lua、Microprocessor ASM、mIRC、MySQL、NSIS、Objective C、OCaml、OpenOffice BASIC、Oracle 8 SQL、Pascal、Perl、PHP、PL/SQL、Python、Q(uick)BASIC、robots.txt、Ruby、SAS、Scheme、SDLBasic、Smalltalk、Smarty、SQL、T-SQL、TCL、thinBasic、Uno IDL、VB.NET、Visual BASIC、Visual Fox Pro、Winbatch、XML

No.445
08/26 21:41

edit


PHPの有用なソースが多数登録されているサイト http://www.phpclasses.org/

なかなかいいクラスがそろっています。

http://www.phpclasses.org/


No.444
06/15 16:07

edit


PHPからunixシェルコマンドを実行しその結果を取得する。

シェルコマンドを実行する関数は

・shell_exec() もしくは バッククォート(`)でコマンドを囲む
・passthru()
・system()
・exec()
・popen()
・proc_open()

と6つありますが、

それぞれの違いは

・shell_exec() 「実行結果の出力がテキスト」のコマンドを実行する場合に使用する
・passthru()  「実行結果の出力がバイナリ」のコマンドを実行する場合に使用する
・system()   コマンド実行結果のうち最後の一行だけ取得
・exec()     コマンド実行結果を指定した変数へ返す(配列で取得)
・popen()     プロセスへのファイルポインタをオープンする
・proc_open()  プロセスへの入出力用ファイルポインタを開く

shell_exec()【コマンド実行結果を全て取得】(スカラーで取得)

passthru()【コマンド実行結果を直接標準出力へ出力。戻り値はナシ。指定した変数へUnixコマンド実行結果が帰る】

passthru()関数はexec()関数と同様にコマンドを実行します。 引数 return_var を指定した場合、 Unix コマンドのステータスで置換されます。Unix コマンドからの出力がバイナリデータであり、 ブラウザーへ直接返す必要がある場合 passthru()を 使用する必要があります。

system()【コマンド実行結果のうち最後の一行だけ取得】

exec()【コマンド実行結果を指定した変数へ返す】(配列で取得)

popen()【プロセスへのファイルポインタをオープンする】

proc_open()【プロセスへの入出力用ファイルポインタを開く】

となっています。

また passthru() 、 system() はコマンド実行結果を標準出力(画面)に出力します。

なのでよく使うのは shell_exec(), exec() という事になります。

プログラムの終了コードを調べる必要があるときには exec() を使いましょう。


◆ shell_exec() の使い方

$output = shell_exec('ls -lart');
もしくは
$output = `ls -lart`;

◆ exec() の使い方

exec ( コマンド, 出力, 戻り値 );

コマンド:文字列(実行するコマンド)

出力:配列(実行結果を格納する配列)

戻り値:数値(戻り値を格納する変数)

です。

具体的には下記のように記述します。

$command = 'ls -la';
$output = array();
$ret = null;
exec( $command, $output, $ret );
print_r( $output );

◆ 標準エラーを取得するには。

shell_exec も exec も、結果を取得するのは標準出力(STDOUT)だけです。

標準エラー(STDERR)を取得するにはコマンドの最後に

2>&1

を追加するとよいでしょう。

例:

$command = 'ls -l';
$output = shell_exec("{$command}  2>&1");
print_r($output);
No.443
01/18 11:34

edit

現在の日付を求める

現在の日付を求めるには

$today = getdate();
print("$today[year]年$today[mon]月$today[mday]日¥n");

ただし、プログラムで日付を扱うときは桁を揃えた方が扱いやすいので

$today = getdate();
$year=sprintf("%04d",$today['year']);
$month=sprintf("%02d",$today['month']);
$day=sprintf("%04d",$today['day']);

がよいかと思われます。


No.436
05/16 21:48

edit


Smartyテンプレート内にcss定義など {} を含む文字列を記述する。

Smartyでは {} は変数を囲うマークアップとなります。

たとえば

.style2 {
font-size: small
}

はエラーとなってしまう。

これを防ぐには

.style2 {ldelim}
font-size: small
{rdelim}

と表記するか、

{literal}
.style2 {
font-size: small
}
{/literal}

と記述します。

No.435
07/25 15:25

edit

Smarty

PHPのプロセス番号を取得する

プロセス番号を取得する

PHPで実行中のプロセス番号を取得するには

$pid = getmypid();

と記述します。

( $pid にプロセス番号が返ってきます)


No.434
05/16 21:49

edit


PHPによるウェブサイトクローラー

■ サイトクローラー(巡回ロボット)クラス phpcrawl

・http://sourceforge.net/projects/phpcrawl/

※ phpcrawl には下記の不具合があります(2007.01.23現在)

・URI正規化が出来ない

・巡回間隔を設定できない(一気にアクセスしに行く)

・HTTPステータス 403 を理解しない


No.433
08/23 19:48

edit


PHPでXMLパースしてオブジェクトまたはハッシュに変換する

● 1. PHPでXMLをパースしてハッシュ(配列)に変換する

こちらの関数を使用すると簡単に取得できます。
が、次の <dddd>タグのような attributes が取得できません。( Id="id:pass" が無視される)
<eeee>タグ内の attributes は取得できます。

$xml = <<< DOC_END
<aaaa Version="1.0">
   <bbb>
     <cccc>
       <dddd Id="id:pass">テスト</dddd>
       <eeee name="hearaman" age="24" />
     </cccc>
   </bbb>
</aaaa>
DOC_END;
function xml2array($xml){
    $xml = preg_replace('/(<\/?)\w+:([^>]*>)/', '$1$2', $xml); //get rid of namespaces
    $xml = simplexml_load_string($xml);
    return json_decode(json_encode($xml),true); //use built-in stuff
}

結果

Array
(
    [@attributes] => Array
        (
            [Version] => 1.0
        )
    [bbb] => Array
        (
            [cccc] => Array
                (
                    [dddd] => テスト
                    [eeee] => Array
                        (
                            [@attributes] => Array
                                (
                                    [name] => hearaman
                                    [age] => 24
                                )
                        )
                )
        )
)

● 2. PHPでXMLをパースしてハッシュ(配列)に変換する

完璧に取得したい場合はこちらがおすすめです。

function XMLtoArray($xml) {
    $previous_value = libxml_use_internal_errors(true);
    $dom = new DOMDocument('1.0', 'UTF-8');
    $dom->preserveWhiteSpace = false;
    $dom->loadXml($xml);
    libxml_use_internal_errors($previous_value);
    if (libxml_get_errors()) {
        return [];
    }
    return DOMtoArray($dom);
}

function DOMtoArray($root) {
    $result = array();
    if ($root->hasAttributes()) {
        $attrs = $root->attributes;
        foreach ($attrs as $attr) {
            $result['@attributes'][$attr->name] = $attr->value;
        }
    }
    if ($root->hasChildNodes()) {
        $children = $root->childNodes;
        if ($children->length == 1) {
            $child = $children->item(0);
            if (in_array($child->nodeType,[XML_TEXT_NODE,XML_CDATA_SECTION_NODE])) {
                $result['_value'] = $child->nodeValue;
                return count($result) == 1
                    ? $result['_value']
                    : $result;
            }

        }
        $groups = array();
        foreach ($children as $child) {
            if (!isset($result[$child->nodeName])) {
                $result[$child->nodeName] = DOMtoArray($child);
            } else {
                if (!isset($groups[$child->nodeName])) {
                    $result[$child->nodeName] = array($result[$child->nodeName]);
                    $groups[$child->nodeName] = 1;
                }
                $result[$child->nodeName][] = DOMtoArray($child);
            }
        }
    }
    return $result;
}

結果

Array
(
    [aaaa] => Array
        (
            [@attributes] => Array
                (
                    [Version] => 1.0
                )
            [bbb] => Array
                (
                    [cccc] => Array
                        (
                            [dddd] => Array
                                (
                                    [@attributes] => Array
                                        (
                                            [Id] => id:pass
                                        )
                                    [_value] => テスト
                                )
                            [eeee] => Array
                                (
                                    [@attributes] => Array
                                        (
                                            [name] => hearaman
                                            [age] => 24
                                        )
                                )
                        )
                )
        )
)

引用元 : https://goo.gl/Ko7fwC

● 名前空間を削除する

名前空間の名前が付いてくるのが邪魔な場合は変換前に次の1行を噛ませて名前空間を削除しておきましょう。

$xml = preg_replace('/(<\/?)\w+:([^>]*>)/', '$1$2', $xml); //get rid of namespaces

● 3. PHPでXMLをパースしてオブジェクトまたはハッシュに変換する

よくネットで見かけるやり方です。通常これでも問題ないのですが、 <ns2:ItemDimensions> のようなネーム空間を持つXMLを変換できない時があります。

$xml = simplexml_load_string($html);
$xml_array = json_decode( json_encode( $xml ), TRUE );

● Message: simplexml_load_string(): Entity: line 1: parser error : Unsupported encoding x-sjis-cp932 エラーとなる場合の対処

返される xml が x-sjis-cp932 エンコーディングの場合エラーとなるので、次のように変換する。

 $data = mb_convert_encoding($data,"UTF-8");
 $data = str_replace("x-sjis-cp932","UTF-8",$data);
No.422
02/01 17:07

edit

PEAR
XML

No.356
11/08 17:28

edit


Smartyで 配列の中に要素があるかを調べる (in_array )

Smartyで PHP のin_array を使いたいなと思ったんですが、プラグインを書かなくても使えます。

$shop_idが配列$listの中に入っているかどうかを調べるには以下のようにする
テンプレートファイル内で以下のように記述する。
{if $shop_id|in_array:$list}すでに入っています
{else}配列の中には存在しません
{/if}

No.354
03/23 13:56

edit

Smarty
配列

PEAR Cache_Lite を使ってみる

Cacheクラス PEAR Cache_Lite を使ってみる。

インストールはコマンド一発。簡単。

pear install Cache_Lite

composerコマンドでも入れられます

composer require pear/cache_lite 

レンタルサーバの場合は http://pear.php.net/package/Cache_Lite/download からダウンロード

ソースは下記のような感じ

// クラス読み込み
require_once('Cache/Lite.php');
// IDのセット
$cache_id = '123456';
// オプション
$options = array(
	'cacheDir'               => '/tmp/',
	'caching'                => 'true',	// キャッシュを有効に
	'automaticSerialization' => 'true',	// 配列を保存可能に
	'lifeTime'	             => 1800,	// 60*30(生存時間:30分)
	'automaticCleaningFactor' => 200,	// 自動で古いファイルを削除(1/200の確率で実行)
	'hashedDirectoryLevel'    => 1,		// ディレクトリ階層の深さ(高速になる)
);
// オブジェクトのnew
$cache=new Cache_Lite($options); 
// キャッシュデータがあるかどうかの判別
if( $cache_data=$cache->get($cache_id) ){
    $buff = $cache_data;
}
else{
	// キャッシュデータがない。DBからデータを読み込む処理
	// データ取得処理ここから
	// ……………………… $read_data にデータを入れておく
	// データ取得処理ここまで
	$buff = $read_data;
	$cache->save($buff, $cache_id);
}
print_r($buff);

簡単、便利。 古くなったキャッシュファイルも自動で削除してくれるので余計なコーディングをしなくてすみます。

オプションについてのマニュアル:http://pear.plus-server.net/package.caching.cache-lite.cache-lite.cache-lite.html

マニュアル:http://pear.php.net/manual/en/package.caching.cache-lite.php

他のおすすめキャッシュクラスとしては phpfastcache : https://packagist.org/packages/phpfastcache/phpfastcache
がおすすめです

No.334
12/23 17:01

edit

高速化
PEAR

【Smarty】で{foreach}の繰り返し回数を取得する

Smartyで繰り返しの回数を取得(カウント)するには予約変数 {$smarty.foreach.ループ名}を使用する。

{ foreach from=$loop key="key" item="value" }
 名前は{$value.name}です
{/foreach}

というループ箇所がある場合は、【name="任意のループの名前"】をつけて

【$smarty.foreach.任意のループの名前.iteration】で参照する。

(なお、iteration の値は1からはじまる。)

{ foreach from=$loop key="key" item="value" name="loopname"}
 名前は{$value.name}です
 ループ回数は{$smarty.foreach.loopname.iteration}です
{/foreach}

でOK。

また5回ループするごとに何か処理を行いたい場合は {if} を使う

{ foreach from=$loop key="key" item="value" name="loopname"}
 名前は{$value.name}です
 {if $smarty.foreach.loopname.iteration%5==0}5回繰り返しました{/if}
{/foreach}
No.333
11/24 11:20

edit

Smarty

PHPで1の位を切り上げ、切り捨て、四捨五入を行う

PHPで1の位を切り上げ、切り捨てるには以下のようにするといいでしょう

function floor_1( $no ){
	return floor(($no/10))*10;
}
function ceil_1( $no ){
	return ceil(($no/10))*10;
}
function round_1( $no ){
	return round(($no/10))*10;
}

$data = floor_1(1957.5); // 1950 になります。
$data = ceil_1(1957.5); // 1960 になります。
$data = round_1(1957.5); // 1960 になります。

10の位で切り上げ、切り捨てるには以下のようにするといいでしょう

function floor_10( $no ){
	return floor(($no/100))*100;
}
function ceil_10( $no ){
	return ceil(($no/100))*100;
}

その他数値関数は以下のとおり

srand       乱数初期化
rand        乱数発生
floor       切り捨て整数化
ceil        切り上げ整数化
round       四捨五入
sqrt        平方根
No.315
07/05 13:24

edit


PHPで環境変数一覧を取得する

PHPで環境変数一覧を取得するには

print "<pre>\n";
print_r($_SERVER);
print "</pre>\n";

とする。

これはつまり $_SERVER 変数を取得してきているので、それぞれを参照するには

$hostname = gethostbyaddr($_SERVER['REMOTE_ADDR']);
$data =
"
------------------------------------------------------
Host  : {$hostname}
Addr  : {$_SERVER['REMOTE_ADDR']}
Agent : {$_SERVER['HTTP_USER_AGENT']}
------------------------------------------------------
";
print $data;

という風に記述する。

また getenv() という環境変数を取得する関数はWindows版PHPでは使えないことがあるので使用しないほうがよい。

(またはgetenv()が使えないwindowsサーバで使用した場合nullが返るのでその場合の処理を入れておくほうが良い。)

No.309
07/26 09:15

edit

全角カタカナにマッチする正規表現

全角カタカナにマッチする正規表現

preg_match( '/[ァ-ヶ]+/',$text );

参考:Unicode対応文字コード表

http://ash.jp/code/unitbl21.htm

No.304
08/08 14:22

edit

正規表現
日本語

PHPでクッキーの読み書きをする

■PHPでクッキーを書き込むには

setcookie( $name, $value, $timeout, $path, $domain);

$name:名前

$value:値

$timeout:有効期限

$path:対象となるパス(指定したパス以下でcookieが有効)

$domain:対象となるドメイン

setcookie ( $name, $value, time( )+90*24*3600, '/' );  //90日で期限切れ

PHPでクッキーの値を削除するには

名前だけをセットして、値を空文字にして、【時間をnullにして】 setcookie を実行する

setcookie ( $name, '', null, '/' );  //クッキーの値を削除

PHPでクッキーを読み込むには

$data= $_COOKIE['cookie_name'];

とする。

No.300
04/20 16:26

edit

Cookie

Smartyを使ってRSS用日付を表示させる

■ 日付表示の基本

{$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}
 ↓
2007-07-04 18:00:00

■ RSS用 日付表示

<pubDate>{$date|date_format:"%a, %d %b %Y %H:%M:%S"} +0900</pubDate> 

■ RSS用 日付表示(現在の日付を表示する場合)

<pubDate>{$smarty.now|date_format:"%a, %d %b %Y %H:%M:%S"} +0900</pubDate>
↓
<pubDate>Fri, 27 May 2011 14:13:13</pubDate>
No.289
06/30 15:28

edit

Smarty
日付

日本語が入った正規表現で検索、置換を行う

日本語が入った正規表現を使って検索、置換を行うには preg_match , preg_replace を使う

その際文字化けが起こってしまうことが多いが、原因は【/】をエスケープし忘れている

ところにあると思うので、【/】はきちんとエスケープしよう。

1 日本語エンコードを指定する

mb_regex_encoding('UTF-8'); // もしくは SJIS, EUC-JP

2 検索する文字( $find_text )と区切り文字(/)はあらかじめエスケープしておく

$find_text = preg_quote($find_text, '/');

3 正規表現を使って置換を行う

$string=preg_replace("/($find_text)/", "置換する文字列",$string );

これで文字化けもおこらないと思います。

エンコードUTF-8で日本語を使う場合は u オプションを使用します

$string=preg_replace("/($find_text)/u", "置換する文字列",$string );
No.287
02/09 16:10

edit

正規表現
日本語

PHPのタイムアウト【Maximum execution time of 60 seconds exceeded】エラーが出る場合の対応

● PHPの Maximum execution time of 60 seconds exceeded エラーの対応

PHPで処理時間の長いプログラムを実行時に 【Maximum execution time of 60 seconds exceeded】(60のところは任意の数字) が出てプログラムが終了する場合があります。

これは60秒以上かかったので強制終了したというエラーです。 どうしても処理が60秒以上かかる場合はタイムアウトまでの時間を変更します。

/etc/php.ini

max_execution_time = 30
max_input_time = 60

の箇所を修正します。

または PHPソース内に

ini_set("max_execution_time",180); // タイムアウトを180秒にセット
ini_set("max_input_time",180); // パース時間を180秒にセット

● タイムアウトをさせたくない場合

タイムアウトをさせたくない場合は、PHPソース内に

ini_set("max_execution_time",0); // タイムアウトしない
ini_set("max_input_time",0); // パース時間を設定しない

と設定します。
ちなみにPHPをコマンドライン(CLI)から実行する場合のデフォルト設定は 0 です。

No.283
05/31 18:48

edit

エラー対処

多次元配列を結合する

配列を再起的に結合するには

array_merge_recursive

を使用する

array_merge_recursive ( array 配列1, array 配列2 )
No.276
08/12 10:15

edit

配列

Smartyで配列かどうかを判別するには?

Smartyで配列かどうかを判別するには is_array を使用します

{ if is_array($data) }
  { foreach from=$data key="k" item="v" name="loopname" }
    {$v|escape}
  { /foreach }
{ else }
  {$data|escape}
{ /if }
No.262
07/14 15:34

edit

Smarty
配列

RSSフィード(XML)をパースしてPHPオブジェクトに変換する【PEAR::XML_Serializer】

RSSフィード(XML)をパースしてPHPオブジェクト(や配列)に変換するには下記の2通りの方法があります

■1. PEAR::XML_Serializerを使用する方法

xml 文章を配列やオブジェクトにしてくれる PEAR::XML_Serializer

http://pear.php.net/package/XML_Serializer/download

からダウンロード

PEARでのインストール方法

pear install XML_Util
pear install XML_Serializer-0.18.0

でOK!

<b>またはこのファイルをダウンロード(phplib.zip)してサーバーにアップロードします。</b>

使い方

$url = "http://sankei.jp.msn.com/rss/news/points.xml"; // RSSフィードのURL
$xml = file_get_contents($url);
require_once "XML/Unserializer.php";
$parser = new XML_Unserializer(array('parseAttributes' => true));
$parser->unserialize($xml);
$data = $parser->getUnserializedData();
if (PEAR::isError($data)) {   print ('ERROR');   }
print_r($data);

エラー補足は PEAR::isError で行えます。

■2. SimpleXMLElement (要PHP5以降)を使用する方法

使い方

$url = "http://sankei.jp.msn.com/rss/news/points.xml"; // RSSフィードのURL
$xml = file_get_contents($url);
$xml = preg_replace( '/dc:/', 'dc_', $xml );
// <dc:subject> <dc:date> などを取得する場合は : を _ に置換する。
$data_obj = new SimpleXMLElement($xml);
$data = (ARRAY)$data_obj;
print_r($data);

どちらも簡単ですね!

添付ファイル1
phplib.zip ( 37.3 KBytes ) ダウンロード
No.258
03/18 09:59

edit

添付ファイル

XML
PEAR

エラー、警告メッセージをロギングする。

PHPではデフォルトでエラーをログに吐かない。

なので明示的にロギングをするよう設定する。

(PHPスクリプトの最初に記述しておく)

ini_set('log_errors', 1);					// エラーをロギングする

毎回記述するのが面倒な場合は

php.ini の該当箇所に記述する。


No.243
08/12 10:14

edit

エラー対処

ある月の日数を取得する

PHPである月の日数を取得するには

print date("t", time());

とします。


No.226
08/12 10:10

edit


チェックボックスの値を配列で受け取るため name="check[]" とするとJavaScriptで値が受け取れない問題について

JavaScriptでチェックボックスの値を受け取るには

<form name="FM">の<input type="checkbox" name="order_no[]">時
// form_name
var form_name = 'order_no[]';

// length
alert('合計' + document.FM.elements[form_name].length + '個のチェックボックスがあります');

// value
value_array = new Array();
for (i=0; i<document.FM.elements[form_name].length; i++ ){
	if(document.FM.elements[form_name][i].checked == true){
		value_array.push(document.FM.elements[form_name][i].value);
	}
}
alert('合計' + value_array.length + '個チェックされています');
alert(value_array);
No.222
03/31 15:33

edit

配列

PHPで日本語を扱うための設定をする mb_string

phpinfo()で【mbstring.language】の項目を見てみる

デフォルトでは【neutral】になっているので mb_string関連関数が動作しない

そこで実行するPHPスクリプトの先頭の方で以下の関数を実行する

mb_language( "ja");
mb_internal_encoding( "UTF-8"); // もしくは EUC-JP(PHPを記述している文字コードを指定)

尚php.iniの設定は

output_buffering              = Off

(PHPを記述している文字コードと出力文字コードが違う場合は on にする必要があるが、

文字コード変換はframworkで行うのが望ましいのでとりあえずoffでいい)

No.215
08/12 10:17

edit

日本語

Smartyで数字を3桁ごとにコンマで区切る

Smartyで数字を3桁ごとにコンマで区切るには

合計: {$sum|number_format}円

とします。

No.214
07/14 11:28

edit

Smarty

PHPでfillinform

PerlにはHTML::FillInFormという便利なモジュールがありますが
それをPHPでも!
fbisさん作 PHP版 HTML::FillInForm
http://d.hatena.ne.jp/fbis/searchdiary?word=HTML%3a%3aFillInForm



No.193
07/16 12:11

edit

PEAR関連

インストール方法

参考:http://dozo.matrix.jp/pear/index.php/PEAR/HTML_Template_Flexy

インストールされているモジュールの一覧

pear list

pear list-all (現在Stableな最新版のバージョンも表示)

モジュールのバージョンアップ

pear upgrade モジュール名

pearマニュアル

http://pear.php.net/manual/ja/


No.190
08/23 19:30

edit

PEAR

PHPのエラー表示を設定する

PHPのエラー表示を設定する箇所は 1: php.ini 2: phpソース内 3: .htaccess の3箇所あります
E_ALL & ~E_NOTICE を記述する場合の例

● php.ini に記述する場合

error_reporting = E_ALL & ~E_NOTICE

● phpソース内に記述する場合

error_reporting(E_ALL ^ E_NOTICE);

● .htaccessに記述する場合

php_value error_reporting 6135

.htaccess に記述する場合は定数は使えませんので数値で指定します
http://php.net/manual/ja/errorfunc.constants.php

● エラーが全く表示されない場合

php.ini中の display_errors が Off になっているとエラーが一切表示されなくなります。 エラーがまったく表示されないときはphpソース内に

ini_set( 'display_errors', "1" );

とします。

また phpinfo(); で表示される画面または次のコマンドから php.ini を探し出して php.ini ファイルを書き換えます。

display_errors = Off
  ↓
display_errors = On

php.ini の 場所を調べるコマンド

php -r "echo phpinfo();" | grep "php.ini"
No.70
01/10 13:42

edit

エラー対処

PHPの代表的なテンプレートエンジンsmartyのダウンロードとインストール

● 1. Smarty動作条件を確認する

Smarty動作条件は

Smarty 3.x: PHP 5.2+
Smarty 2.x: PHP 4 or 5

となっています。 条件に当てはまるバージョンのSmartyをダウンロードします。

● 2. ダウンロードした「Smarty-XXXXX.tar.gz」または「Smarty-XXXXX.zip」を解凍する

● 3. 解凍して出来たディレクトリ内の 「libsフォルダ」をFTPでアップロード(プログラムがあるphpディレクトリにアップロード)

● 4. テンプレート用フォルダを作成しパーミッションを変更する

templates (パーミッションは変更しなくてよい)
templates_c (パーミッション 777 に変更する)

● 5. テンプレート用フォルダ(templates)にテンプレートファイルをアップロード

テンプレートファイルを置くフォルダは「templates」です。 templates_cフォルダは Smarty が使用するフォルダですので一切触る必要はありません。

● 6. ディレクトリ例

このようなディレクトリ構成になります

 |-- [libs]
 |-- [templates]
 |-- [templates_c]
 |-- 実行するプログラム.php

● 7. phpコーディング例 ( ./templates/test.html を表示させる。)

require_once('Smarty/Smarty.class.php');
$template = new Smarty;
$template->display('test.html');

以上。簡単ですね。

■ Smarty3日本語マニュアル

http://www.smarty.net/docs/ja/

No.1
09/04 13:15

edit

Smarty