2012年4月6日金曜日

apache2からのphpが実行できなかった時のメモ

php5.4をソースからビルドした際に何かやってしまったのか、ブラウザからphpの実行がされなくなりました。
phpファイルがダウンロードされる状態になったので、その時の対応メモ

まず、こちらのページを参考にしました。

以下のファイルが見つかりませんでした。
/etc/apache2/mods-available/php5.conf
php関連のは以下のファイルがありました。
/etc/apache2/mods-available/php5filter.conf
/etc/apache2/mods-available/php5filter.load
次に、一番最初にphpとapacheをインストールした時に参考にしたページの通りに、設定したのですがダメでした。

グーグル先生で色々調べてたら、非常に参考になるページが見つかりました。
参考ページの通りに有効なモジュール一覧に、php関連のモジュールがありませんでした。
インストールされていた、php関連のモジュールを有効にしてみました。

sudo a2enmod php5filter
apacheを再起動し、ブラウザから確認。

php5.4じゃない、、、
php5.4をインストールした時は、apacheに関係するconfigureオプションつけていなかったので、ビルドし直してインストールする。

./configure --enable-mbstring \
--prefix=/usr/local/php \
--enable-mbregex \
--with-zlib=/usr/local/zlib \
--with-zlib \
--enable-zip \
--enable-ftp \
--enable-pcntl \
--enable-soap \
--with-mcrypt \
--with-gd \
--enable-pdo \
--with-pear \
--with-readline \
--with-apxs2=/usr/bin/apxs2 \
--with-mysql=/usr/local/mysql
mysqlも利用できるようにする。
mysql5.6のインストール時に知った、pacoを使って管理できるようにする。
make
sudo paco -D make install
先程有効にしたモジュールを無効にする。
sudo a2dismod php5filter
apacheリスタート後、再度ブラウザから確認

php5.4にかわったことを確認できました。
apt-getでインストールしたパッケージとかと混ざって変なことになってそうなので、そのうち整理しようかなと思います。

2012年4月5日木曜日

mysql5.6インストール

mysql5.6のインストールをしたときの備忘録。
mysql5.6はまだ評価版なので、ソースからビルドしてインストールしました。
こちらの記事を参考にさせていただきました。

pacoというソースからビルドして入れたものに関しても、パッケージ管理みたいにできるものがあるのを知りました。
参考サイトの通りの手順でpacoをインストールしてから、mysqlのインストールを開始しました。


ソースダウンロード、ビルド
wget -O mysql-5.6.4-m7.tar.gz http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.4-m7.tar.gz/from/http://ftp.iij.ad.jp/pub/db/mysql/

tar zxvf mysql-5.6.4-m7.tar.gz
cd mysql-5.6.4-m7/
cmake .
make
sudo paco -D make install
ここまでで、インストールは完了

次はmysqlの設定をして起動まで

sudo groupadd mysql
sudo useradd -r -g mysql mysql

sudo ln -s /usr/local/mysql/bin/ /usr/local/bin/

sudo mkdir /var/log/mysql/
sudo touch /var/log/mysql/error.log
sudo touch /var/log/mysql/query.log
sudo touch /var/log/mysql/slow.log
sudo chown -R mysql. /var/log/mysql/

sudo cp support-files/my-large.cnf /etc/my.cnf
export PATH="$PATH:/usr/local/mysql/bin"
sudo ./scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql
sudo bin/mysqld_safe --user=mysql &
mysqlをスタートし、バージョン確認

これでmysql5.6のインストールができたことが確認できました。

2012年3月29日木曜日

apt-getのpost-installationスクリプトエラー

パッケージインストール時に中途半端な状態になってしまったのか、対象のパッケージを apt-get purge や install -f, autoremoveしようとするが、エラーになってしまう状態になりました。

isuzuki@isuzuki-VirtualBox:~$ sudo apt-get purge oracle-java7-installer

---省略---

oracle-java7-installer を削除しています ...
update-alternatives: エラー: `build' は不明な引数です
dpkg: oracle-java7-installer の処理中にエラーが発生しました (--purge):
サブプロセス インストール済みの pre-removal スクリプト はエラー終了ステータス 2 を返しました
dpkg: クリーンアップ中にエラーが発生しました:
サブプロセス インストール済みの post-installation スクリプト はエラー終了ステータス 10 を返しました
以下のパッケージの処理中にエラーが発生しました:
oracle-java7-installer
E: Sub-process /usr/bin/dpkg returned an error code (1)

パッケージに関して確認
isuzuki@isuzuki-VirtualBox:~$ sudo dpkg --audit
以下のパッケージは最初の設定中に問題が発生したため、設定が終了していません。
dpkg --configure <パッケージ> か dselect で設定 (configure) メニューオプショ
ンを使って設定作業を再試行しなければなりません:
 oracle-java7-installer Sun Java(TM) Development Kit (JDK) 7

configure実行
isuzuki@isuzuki-VirtualBox:~$ sudo dpkg --configure oracle-java7-installer
oracle-java7-installer (7u3-0~webupd8~8) を設定しています ...
dpkg: oracle-java7-installer の処理中にエラーが発生しました (--configure):
 サブプロセス インストール済みの post-installation スクリプト はエラー終了ステータス 10 を返しました
以下のパッケージの処理中にエラーが発生しました:
 oracle-java7-installer
参考にさせていただいた、エントリに書いてあった通り、
/var/lib/dpkg/info の以下のファイルを削除しました。
oracle-java7-installer.postinst
oracle-java7-installer.postrm
oracle-java7-installer.prerm


再度configure実行
isuzuki@isuzuki-VirtualBox:~$ sudo dpkg --configure oracle-java7-installer
oracle-java7-installer (7u3-0~webupd8~8) を設定しています ...

試しにインストール
isuzuki@isuzuki-VirtualBox:~$ sudo apt-get install oracle-java7-installer
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています               
状態情報を読み取っています... 完了
oracle-java7-installer はすでに最新バージョンです。
正常な状態になったようです。

より詳しくは、参考にさせていただいたエントリ
非常に勉強になり、再びこのような事態が起きても対応できるように覚えておこう思います。

2012年3月25日日曜日

PHPでscanf

PHP extension の勉強をしていて、C言語を久々に触っていた時に、PHP で scanf みたいなのって書いたことないなと思ったので、調べて書いてみました。

こちらのエントリに書いてあったことをそのまま試してみました。

・scanf のサンプル
<?php
echo '文字列を入力してください。' ."\n";
fscanf(STDIN, '%s', $str);
var_dump($str);

echo '文字列を入力してください。' ."\n";
$stdin = fopen('php://stdin', 'r');
$str = trim(fgets($stdin));
fclose($stdin);
var_dump($str);


・実行結果


どちらも求める結果になりました。
違いに関しては、僕が参考にしたエントリを見ていただければと思います。

2012年3月20日火曜日

PHP5.4、配列文法

PHP5.4 から配列を簡単に書けるようになりました。

・今までの配列定義
<?php
$arr = array('a' => 'test1',
'b' => 'test2',
'c' => 'test3',
);


・新たな配列定義
<?php
$arr = ['a' => 'test1',
'b' => 'test2',
'c' => 'test3',
];


配列定義をループさせてみましたが、特にパフォーマンスに差はありませんでした。
今まで使用してきた言語によると思いますが、PHP5.4以前のころから利用している人は、新しい書き方はあまりしないかもですね。

2012年3月19日月曜日

PHP5.4インストール、Traitsの利用

PHP5.4が安定版としてリリースされたので、インストールしてみました。
インストール手順はこちらの記事を参考にしました。

・ソース取得
wget http://www.php.net/get/php-5.4.0.tar.gz/from/jp.php.net/mirror -O php-5.4.0.tar.gz

・tarファイル展開
tar xvf php-5.4.0.tar

・コンパイルオプション設定
cd php-5.4.0
./configure --enable-mbstring \
--prefix=/usr/local/php \
--enable-mbregex \
--with-zlib=/usr/local/zlib \
--with-zlib \
--enable-zip \
--enable-ftp \
--enable-pcntl \
--enable-soap \
--with-mcrypt \
--with-gd \
--enable-pdo \
--with-pear \
--with-readline \

・make、インストール
make
sudo make install

・確認


これでPHP5.4のインストールが完了しました。


新機能の Traits を試してみました。
Traits はソースの再利用に有効になるかもしれません。詳しくはマニュアル に書いています。

Traits を利用したシングルトン
<?php
trait TraitSingleton {
private static $_instance;

private function __construct() {
}

public static function getInstance() {
if (isset(self::$_instance) === false) {
self::$_instance = new static;
}

return self::$_instance;
}
}


シングルトン Traits 利用
<?php
require_once('/home/isuzuki/dev/php/php5.4/TraitSingleton.php');

abstract class Base {
}

class TraitSample1 extends Base {
use TraitSingleton;

private function __construct() {
}

public function echoClass() {
echo __CLASS__ ."\n";
return true;
}
}

class TraitSample2 extends Base {
use TraitSingleton;

private function __construct() {
}

public function echoClass() {
echo __CLASS__ ."\n";
return true;
}
}

$obj1 = TraitSample1::getInstance();
$obj1->echoClass();
$obj2 = TraitSample2::getInstance();
$obj2->echoClass();


実行結果


これで、Traitsが無事利用できていることがわかりました。

2012年3月12日月曜日

HipHop for PHP インストール

FacebookのHipHop for PHPをUbuntu 11.10にインストールしてみました。
手順は、Facebookが公開している手順(Building and Installing on Ubuntu 11.10)どおりに行えば問題ないです。

何点かインストール中に躓いたところで、OSを32bitにしていたので、cmakeの時点でwarningが出ました。
32bitでのcmake結果です。


32bitでも動かせるようですが、OSを64bitにして再トライしました。

同様の手順で、cmakeしたところ、特に何もメッセージも出ないので、続けてmakeし、実行しました。
ソースの修正を見逃していて、segmentation faultで落ちました。

こちらも、手順に書いてあるように、
lib/ssluse.c をgit hubのとおりに修正、
src/runtime/ext/extension.cpp も同様にgit hubのとおりに修正。

make後、無事実行できることを確認しました。

サンプルプログラムを、HipHopで実行してみました。
・PHPソース
<?php
echo 'HipHop for PHP' ."\n";
echo 'Hello World' . "\n";


実行結果


実行後、指定したディレクトリ以下には実行ファイルや、C++に変換されたソースなどがありました。
実行ファイルの結果


・C++ソース
/tmp/hphp/php/home/isuzuki/dev/php/hello.cpp

#include <runtime/base/hphp.h>
#include <sys/literal_strings_remap.h>
#include <sys/scalar_arrays_remap.h>
#include <sys/scalar_integers_remap.h>
#include <sys/global_variables.h>
#include <sys/cpputil.h>
#include <php//home/isuzuki/dev/php/hello.fws.h>
#include <php//home/isuzuki/dev/php/hello.h>

// Dependencies
#include <runtime/ext/ext.h>
namespace hphp_impl_starter {}

namespace HPHP {
////////////////////////////////////////////////////////////////////////////
///

/* preface starts */
extern CallInfo ci_;
/* preface finishes */
Variant pm_php$$home$isuzuki$dev$php$hello_php(bool incOnce, LVariableTable*
variables, Globals *globals) {
PSEUDOMAIN_INJECTION(run_init::/home/isuzuki/dev/php/hello.php, pm_php$$ho
me$isuzuki$dev$php$hello_php);
LVariableTable *gVariables ATTRIBUTE_UNUSED = (LVariableTable *)g;
echo(NAMSTR(s_ssedffcbbc, "HipHop for PHP\n"));
echo(NAMSTR(s_ssc9bf8a1a, "Hello World\n"));
return true;
}
namespace hphp_impl_splitter {}

////////////////////////////////////////////////////////////////////////////
///
}


/tmp/hphp/php/home/isuzuki/dev/php/hello.fws.h


#ifndef __GENERATED_php__home_isuzuki_dev_php_hello_fws_h6d9aa4dd__
#define __GENERATED_php__home_isuzuki_dev_php_hello_fws_h6d9aa4dd__


namespace HPHP {
////////////////////////////////////////////////////////////////////////////
///

// 1. Static Strings
extern StaticString s_ssc9bf8a1a;
extern StaticString s_ssedffcbbc;

// 2. Static Arrays

// 3. Static Variants





////////////////////////////////////////////////////////////////////////////
///
}


#endif // __GENERATED_php__home_isuzuki_dev_php_hello_fws_h6d9aa4dd__


/tmp/hphp/php/home/isuzuki/dev/php/hello.h


#ifndef __GENERATED_php__home_isuzuki_dev_php_hello_h344dcfd5__
#define __GENERATED_php__home_isuzuki_dev_php_hello_h344dcfd5__


// Declarations

namespace HPHP {
////////////////////////////////////////////////////////////////////////////
///

// Includes and Functions
Variant pm_php$$home$isuzuki$dev$php$hello_php(bool incOnce, LVariableTable*
variables, Globals *globals);

// Constants

////////////////////////////////////////////////////////////////////////////
///
}

#endif // __GENERATED_php__home_isuzuki_dev_php_hello_h344dcfd5__


このようなソースができていました。
これで、インストールは完了したので、今後色々と使ってみようと思います。

2012年3月1日木曜日

ファイルダウンロード

PHPでcsvファイルをダウンロードするサンプルプログラムを作成してみました。

最初のソースはファイルを作成して、ダウンロードさせるパターンです。
ファイル内容が、膨大な量になる時はこちらの方法がいいのかと思います。
<?php
$file = '/tmp/file.csv.' .getmypid();
$fp = fopen($file, 'w');
if ($fp === false) {
error_log('file open error');
exit(1);
}

$header = array('num',
'line',
'data',
);
fputcsv($fp, $header);

for($i=1;$i<=100;$i++) {
$line = array($i,
'line' . $i,
'data' . $i,
);
fputcsv($fp, $line);
}

fclose($fp);

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="download.csv"');
header('Content-Length: '.filesize($file));
readfile($file);

@unlink($file);
exit(0);



二つ目のソースは出力バッファを利用したものになります。
自分はファイルの内容問わず、ファイルを作成する方法でやっていたのですが、内容が大した量ではないときはこちらの方法の方が効率良いかと思います。
<?php
$fp = fopen('php://output', 'w');
if ($fp === false) {
error_log('file open error');
exit(1);
}

ob_start();
$header = array('num',
'line',
'data',
);
fputcsv($fp, $header);

for($i=1;$i<=100;$i++) {
$line = array($i,
'line' . $i,
'data' . $i,
);
fputcsv($fp, $line);
}

$str = ob_get_contents();
fclose($fp);
ob_end_clean();

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="download.csv"');
header('Content-Length: '.strlen($str));
echo $str;

exit(0);



入出力ストリームへのアクセスとか全然知らなかったので、非常に勉強になりました。
PHPマニュアル

2012年1月27日金曜日

PHP json_decode ではまったこと

配列をjsonに変換し、POSTした画面先で再度配列に直す処理を書いていたときにはまったこと。

json_decodeの第二引数を「true」にして連想配列にすれば良かったのですが、見逃していて自力で配列にキャストした時に、よくわからないことが起こりました。

自力で配列へのキャスト
<?php
$arr = array(1 => 'hoge',
'a' => 'fuga',
2 => 'piyo',
'b' => 1234,
);

$json = json_encode($arr);
var_dump($json);

$json_arr = (array)json_decode($json);
var_dump($json_arr);

foreach ($json_arr as $k => $v) {
var_dump($json_arr[$k]);
}


このコードの実行結果は以下の様になりました。



エラーが出るのでキーに「"1"」の文字列が入ったのかなとか思ったのですが、結局そのキーを指定しても、ダメでした。
結局なぜダメなのかはわからずですが、json_decodeの第二引数を「true」にした場合は、問題なかったのでそちらでやるようにしました。
原因知りたいですが、未だわからずです。


第二引数に「true」を師弟
<?php
$arr = array(1 => 'hoge',
'a' => 'fuga',
2 => 'piyo',
'b' => 1234,
);

$json = json_encode($arr);
var_dump($json);

$json_arr = json_decode($json, true);
var_dump($json_arr);

foreach ($json_arr as $k => $v) {
var_dump($json_arr[$k]);
var_dump($json_arr[(string)$k]);
}


このコードの実行結果は以下の様になりました。


jsonから配列に変換する時は、json_decodeを利用するとキーが数字の場合は、int型のキー配列に変換してくれるようです。

2012年1月10日火曜日

SVGの簡単なサンプル

SVGというものを最近知ったので、サンプルを書いてみた。
サンプルと言っても、下記ページを読んで、そのまま書いて見ただけです。
ASCII.jp

サンプルHTML
<html>
<head>
<meta charset="UTF-8" />
<title>SVGサンプル</title>
</head>
<body>
<table border="1">
<tr>
<th><div><p>四角</p></div></th>
<th><div><p>角丸四角</p></div></th>
<th><div><p>正円</p></div></th>
<th><div><p>楕円</p></div></th>
<th><div><p>直線</p></div></th>
<th><div><p>連続直線</p></div></th>
<th><div><p>多角形</p></div></th>
<th><div><p>ベジエ曲線</p></div></th>
<th><div><p>JSで記述</p></div></th>
</tr>
<tr>
<td width="100" height="100">
<svg>
<rect x="1" y="1" fill="blue" stroke="red" width="100" height="100">
</svg>
</td>
<td width="100" height="100">
<svg>
<rect x="1" y="1" fill="blue" stroke="red" width="100" height="100" ry="20">
</svg>
</td>
<td width="100" height="100">
<svg>
<circle cx="50" cy="50" r="50" fill="blue" stroke="red">
</svg>
</td>
<td width="100" height="100">
<svg>
<ellipse cx="50" cy="50" rx="50" ry="30" fill="blue" stroke="red">
</svg>
</td>
<td width="100" height="100">
<svg>
<line x1="1" y1="1" x2="100" y2="100" stroke="blue">
</svg>
</td>
<td width="100" height="100">
<svg>
<polyline points="1,1 50,100 100,1" fill="none" stroke="blue">
</svg>
</td>
<td width="100" height="100">
<svg>
<polygon points="1,1 50,100 100,1" fill="none" stroke="blue">
</svg>
</td>
<td width="100" height="100">
<svg>
<path d="M 1,1 C 33,100,66,20,100,30" fill="none" stroke="blue">
</svg>
</td>
<td width="100" height="100">
<form>
<input type="button" value="直線を描く" onclick="drawLine()" />
</form>
<script><!--
function drawLine() {
document.getElementById('mySVG').innerHTML = '<svg><line x1="1" y1="100" x2="100" y2="1" stroke="blue">';
}
--></script>
<div id="mySVG"></div>
</td>
</tr>
</table>
</body>
</html>




連続曲線の時に、fill属性をnoneにしないと、黒で内部が塗りつぶされます。
ブラウザは特定以上のバージョンじゃないと、上手く表示されないようです。

これを使えば、僕の用にあまりhtmlとか詳しくなくてもちょっとした図形を書くことができそうです。
以前と比べて導入しやすくなったようです。このような物もあるんだなと思いました。