アーカイブ

‘php’ タグのついている投稿

strtotimeの「-1 month」は1ヶ月前ではない

2012 年 12 月 11 日 コメントはありません

以下に期待するのは「2012年02月」

echo date('Y年m月', strtotime('-1 month', strtotime('2012-03-31')));

答えは「2012年03月」

実際に「-1 month」がどのくらいの値を返してるを以下で調べてみた。


for ($i = 1; $i <= 12; $i++) { $date = sprintf('2012-%02d-01', $i); $day = strtotime($date) - strtotime('-1 month', strtotime($date)); printf("%s %d\n", $date, $day / 86400); } [/php] 対象日、それに対する「-1 month」での日数の順に表示した結果は以下の通り [bash] 2012-01-01 31 2012-02-01 31 2012-03-01 29 2012-04-01 31 2012-05-01 30 2012-06-01 31 2012-07-01 30 2012-08-01 31 2012-09-01 31 2012-10-01 30 2012-11-01 31 2012-12-01 30 [/bash] この結果から、「-1 month」は対象日の先月分の日数をマイナスする処理ということがわかる。 strtotimeで「-1 month」を用いて1ヶ月前の月を取得したい場合、対象日を月の初め、1日をする必要がある。

カテゴリー: php タグ:

Apacheのリバースプロキシを利用してSERVER_NAMEが取れない時

2011 年 5 月 6 日 コメントはありません

Apacheのリバースプロキシを利用して、SERVER_NAMEがリバースプロキシサーバのIPになっちゃう場合は、リバースプロキシ側のApacheに以下の設定を追加。

ProxyPreserveHost On

PHPプログラムでSERVER_NAMEの値を超利用しまくりな場合は、問題ないようならぶち込んじゃってもいいかも。

$_SERVER['SERVER_NAME'] = isset($_SERVER['X_FORWARDED_HOST']) ? $_SERVER['X_FORWARDED_HOST'] : $_SERVER['SERVER_NAME'];
カテゴリー: linux タグ: ,

Mac OSXでApacheの利用

2011 年 5 月 4 日 コメントはありません

システム環境設定>共有>Web共有をチェック

httpd.confの設定

$ sudo vim /etc/apache2/httpd.conf

設定を上書きできないと困るので180行目のAllowOverrideを変更

    AllowOverride All

PHPを利用可能にするため116行目のコメントアウトを外す

LoadModule php5_module        libexec/apache2/libphp5.so

ヴァーチャルホストの設定ファイルvhosts以下に配置し読み込めるように最後の行に追加
デフォルトだと469行目でヴァーチャルホストの設定を読み込んでいるようだが、最終行のIncludeでPHPの設定が行われているので、それ以降に設定を書かないとPHPを利用できないため

Include /private/etc/apache2/vhosts/*.conf 

ヴァーチャルホストの設定ファイルを作成
ファイル名はお好みで

$ sudo vim /etc/apache2/vhosts/httpd-vhosts-hoge.example.com.conf

ファイルはhogeユーザのSite以下にドメインディレクトリを作成し、そこをドキュメントルートにしています
localhostから接続できるようにAllow fromを追加

<VirtualHost *:80>                                                          
    ServerName hoge.example.com
    DocumentRoot /Users/hoge/Sites/hoge.example.com
    <Directory /Users/hoge/Sites/hoge.example.com>
        Allow from ::1
        Allow from 127.0.0.1
    </Directory>
    ErrorLog /var/log/apache2/hoge.example.com-error_log
    CustomLog /var/log/apache2/hoge.example.com-access_log combined
</VirtualHost>

Apache設定ファイルにミスがないかチェック

sudo apache2ctl configtest

大丈夫なようなら再起動

sudo apache2ctl -k restart

hostsファイルに名前解決できるように追加

sudo vim /etc/hosts
::1 hoge.example.com
127.0.0.1 hoge.example.com
カテゴリー: macosx タグ: ,

Twitterのstatus IDが64bitになったことによる問題と対策

2010 年 11 月 7 日 コメントはありません

Snowflake: An update and some very important information – Twitter Development Talk | Google グループ
TwitterのIDが64bitになるとJavaScript等で問題が出るので対策を – F.Ko-Jiの「一秒後は未来」

事前に告知されていましたが、日本時間で11月5日の朝6時にstatus IDが41bitまでの値を利用するようになりました。

     29535221410 以前
1036396793962496 以後

桁が大分増えましたね。

10月20日からレスポンスにstatus IDの文字列である「id_str」が含まれるようになりました。
2週間という短い期間での移行、そもそも告知自体知らない人も多かったかも知れませんが、対応せず「id」の値を利用していた場合不具合が生じる場合があります。

言語、OSによって内部で利用するstatus IDである「id」の型が異なると思いますが、32bitOS環境のPHPでJSONのデコードにjson_decode関数を利用している場合、「id」はfloat型としていました。
float型、浮動小数点数はマニュアルにあるように、およそ 10 進数で 14 桁の精度であり、新しいstatus IDは正確には扱えず以下のようになります。

$ php -r 'var_dump(1036396793962496);'
float(1.0363967939625E+15)

この値をMySQLのinteger型に保存すると、1036396793962500となります。

対策として、「id」ではなく「id_str」を利用するのですが、修正箇所が多く容易ではなかったため、一時しのぎとして取得したJSONに手を加え、「id」自体を文字列型として扱うことにしました。

$json = preg_replace('/"(id|in_reply_to_status_id)":(\d+)/', '"$1":"$2"', $json);

ツイート文字列にも影響がありますが、まず無いであろうと思われる文字列と、近いうちに「id_str」を利用するよう修正するということで。

カテゴリー: 日記 タグ: ,

Mac OS XにPEARのインストール

2010 年 10 月 29 日 コメントはありません
curl http://pear.php.net/go-pear | sudo php

設定はこんな風にした。

 1. Installation prefix ($prefix) : /Library/Php/Pear
 2. Temporary files directory     : $prefix/temp
 3. Binaries directory            : /usr/bin
 4. PHP code directory ($php_dir) : $prefix/PEAR
 5. Documentation base directory  : $php_dir/docs
 6. Data base directory           : $php_dir/data
 7. Tests base directory          : $php_dir/tests
カテゴリー: macosx タグ: ,

PHP5.3.0~2の罠

2010 年 9 月 2 日 コメント 1 件

PHP5.3.3では以下のような「後方非互換の変更」が加えられています。

Methods with the same name as the last element of a namespaced class name will no longer be treated as constructor. This change doesn’t affect non-namespaced classes.

<?php
namespace Foo;
class Bar {
    public function Bar() {
        // treated as constructor in PHP 5.3.0-5.3.2
        // treated as regular method in PHP 5.3.3
    }
}
?>

There is no impact on migration from 5.2.x because namespaces were only introduced in PHP 5.3.
PHP 5.3.3 Released!

どういう事かというと、


PHP Fatal error: Call to undefined method B::B()

PHP5.3.3

A

PHP5.3.xによってPHP4に対する後方互換が崩れたんですが、PHP5.3.3でPHP5.3.x非互換となる代わりにPHP4後方互換が一部戻ったという話。
PEAR::Image_Graphで問題でてました。
PHP5の環境なら以下のように書くので問題は起こらないんですけどね。


カテゴリー: php タグ: ,

PEAR::Services_Twitterのパッチ

2010 年 8 月 24 日 コメントはありません

Services_Twitter_r302262.diff
7904 byte
[md5] 89930ad5cf340af7a101ed74261d4a34

修正
sendOAuthRequest()メソッドでHTTP_OAuth_Exceptionがthrowされる問題
serchメソッドでhttp://search.twitter.comを利用しない問題
blocks/createメソッドでuser_id、screen_nameを指定できない問題
blocks/destroyメソッドでuser_id、screen_nameを指定できない問題
テストでOAuthの場合sourceはアプリケーションになる問題
テストでutf8テストが二重投稿になる問題
テストでOAuthの場合オブジェクトがHTTP_OAuth_Consumer_Responseになる問題

追加
blocks/bloking/idsメソッド (call $t->blocks->blocking_ids())

$ svn export -r 302262 http://svn.php.net/repository/pear/packages/Services_Twitter/trunk Services_Twitter
$ wget http://blog.cheki.net/Services_Twitter_r302262.diff
$ cd Services_Twitter
$ patch -p0 < ../services_twitter.diff
patching file Services/Twitter.php
patching file data/api.xml
patching file tests/900-exceptions.phpt
patching file tests/910-options.phpt
patching file tests/920-utf8.phpt
patching file tests/data/utf8-2.dat
patching file tests/setup.php
カテゴリー: php タグ: , ,

PEAR::Services_Twitterをforkした

2010 年 8 月 19 日 コメントはありません

Services_Twitter
以前パッチが取り込まれたけど、Basic認証でしか確認してなくて、OAuthだとDELETEメソッドで問題がでてました。
その他なんか迷走してる感じだったので、パッチ送りたいなとPEARアカウントを取得しようと申請したのですがレスポンスがないので、とりあえずgithubにぶち込んだ次第です。
バグレポートもパッチ投げるにもPEARアカウントないと半匿名な感じになるので。

cockok's Services_Twitter at master – GitHub

リリース最新は0.6.2ですが、trunkが変更されてたのでそちらをfork。
あいきゃんとすぴーくいんぐりっしゅ。
もちろん書くのも。

ちなみに、DELETEメソッドででる問題は、RFC2616に以下のようなところ。

The DELETE method requests that the origin server delete the resource identified by the Request-URI.
HTTP/1.1: Method Definitions

こっちはPEAR::HTTP_OAuthの問題。

カテゴリー: php タグ: , ,

PEARをローカルにインストール

2010 年 8 月 11 日 コメントはありません

Manual :: 共有ホストでの PEAR のローカルコピーのインストール

既にpearコマンドが利用可能な場合。

$ pear config-create /path/to ~/.pearrc

/path/to/pear以下に諸々配置される設定ファイルが~/.pearrcとして作成される。
この場合、PEARディレクトリは/path/to/pear/phpとなる。

ディレクトリ等、設定をを変更したい場合は、通常通りpear config-setコマンドで。

phpコマンドを実行する際にinclude_pathの設定をしたいが、オプションでは指定できないので、php.iniを別途準備し読むように指定するaliasを設定。

$ cp /etc/php.ini /path/to
$ vim /path/to/php.ini
$ alias php='php -c /path/to/php.ini'

php.iniのinclude_pathの設定は以下のようにローカルのPEARディレクトリしか読み込まない、または、優先的に読み込むように設定。

include_path = ".:/path/to/php"
#include_path = ".:/path/to/php:/usr/share/pear:/usr/share/php"
カテゴリー: php タグ: ,

PHPでクライアントベースのOAuth認証

2010 年 8 月 7 日 コメントはありません

まさに誰得。
ブラウザベースは情報いっぱいあったんだけど、クライアントベースが見つからなかったので。
取得したaccess_token、access_token_secretを利用の仕方は下記で。
PEAR::HTTP_OAuthでxAuth – ぱんぴーまっしぐら

#!/usr/bin/env php
<?php
require_once 'HTTP/OAuth/Consumer.php';

define('CONSUMER_KEY',    'xxxxxxxxxxxxxxxxxxxx');
define('CONSUMER_SECRET', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');

try {

  $http_request = new HTTP_Request2();
  $http_request->setConfig('ssl_verify_peer', false);

  $consumer_request = new HTTP_OAuth_Consumer_Request();
  $consumer_request->accept($http_request);

  $consumer = new HTTP_OAuth_Consumer(CONSUMER_KEY, CONSUMER_SECRET);
  $consumer->accept($consumer_request);

  $consumer->getRequestToken('http://twitter.com/oauth/request_token');
  $url = $consumer->getAuthorizeUrl('http://twitter.com/oauth/authorize');

  if (!$stdin = fopen('php://stdin', 'r')) {
    throw new Exception('stdin open failed');
  }

  echo 'Visit the following URL in your browser to authenticate twitter: ';
  echo $url."\n";
  echo 'Enter Twitter OAuth PIN: ';
  $pin = trim(fgets($stdin, 64));
  $consumer->getAccessToken('http://twitter.com/oauth/access_token', $pin);

  echo 'access_token: '.$consumer->getToken()."\n";
  echo 'access_token_secret: '.$consumer->getTokenSecret()."\n";

} catch (Exception $e) {

  echo $e->getMessage().' in '.$e->getFile().' line '.$e->getLine()."\n";
  exit(1);

}
カテゴリー: php タグ: , ,