PHPプログラムに関する各種メモ書き:タグ「PEAR」での検索

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
エラー対処

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
エラー対処

外部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

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

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

はてなダイアリーキーワード自動リンク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(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のソースコードを整形する 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

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

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

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

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