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);
}
テストファイルをディレクトリ 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'$'"
PHP 5.4からは 5.3までは出力されなかった【E_STRICTエラー】がデフォルトで出力されるようになっています。 なのでPHPのバージョンを 5.3以下から5.4以上に上げるとE_STRICTエラーが表示されることがよくあります。
自分で書いたソースの場合はエラーの内容を調べて修正するのが一番よいでしょう。
http://goo.gl/moKrOg
そもそも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);
外部SMTPサーバを利用してメールを送信するには PEAR:Mail を利用します。
( PEAR:Mail )
( PEAR:Net:SMTP )
( PEAR:Net:Socket )
『例』
送信元 : 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
がおすすめです
phpのソースコードから不要なコメント・スペース・改行を削除するには下記のコマンドが有効です(シェルのコマンドラインやターミナルから実行)
php -w mysource.php > mysource_min.php
これだけです。簡単。
改行も削除されてプチ難読化されたコードになります。
これでは読みづらい、という場合は 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 -i ファイル名(またはディレクトリ名)
でディレクトリごと一括で処理できます。
PEARでTwitter等各種サービスにOAuthログインをする。(https SSL対応)
面倒な方は
http://logic.moo.jp/memo.php?cmd=download&data_id=780&file=780_1.zip
をダウンロードして(lib)フォルダをそのままコピーしてください。
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>'; }
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 を指定すると、キーワード自動リンクの結果ではなく、自動リンクに使われるキーワード一覧が返却されます。省略可
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>
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}
などと書けばはてな記法が使えます。
PHPコード整形ツール PHP_Beautifier を試してみます。
http://pear.php.net/package/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 --help
php_beautifier before.php > after.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/
こちらの関数を使用すると簡単に取得できます。
が、次の <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
)
)
)
)
)
完璧に取得したい場合はこちらがおすすめです。
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
よくネットで見かけるやり方です。通常これでも問題ないのですが、 <ns2:ItemDimensions> のようなネーム空間を持つXMLを変換できない時があります。
$xml = simplexml_load_string($html);
$xml_array = json_decode( json_encode( $xml ), TRUE );
返される xml が x-sjis-cp932 エンコーディングの場合エラーとなるので、次のように変換する。
$data = mb_convert_encoding($data,"UTF-8");
$data = str_replace("x-sjis-cp932","UTF-8",$data);
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
がおすすめです
RSSフィード(XML)をパースしてPHPオブジェクト(や配列)に変換するには下記の2通りの方法があります
xml 文章を配列やオブジェクトにしてくれる PEAR::XML_Serializer
http://pear.php.net/package/XML_Serializer/download
からダウンロード
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 で行えます。
$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);
どちらも簡単ですね!