Hatena::ブログ(Diary)

西新宿のプログラマの日記 このページをアンテナに追加 RSSフィード

2011-11-05

CORE SERVERでIP制限とパスワード認証をサイト全体に導入する方法

備忘録です。

軽く調べたらIP制限については情報がなかったので、実際に試してちゃんと動作したのでめもめも。

とりあえず、パスワード生成して、.htpasswdに保存する。

パスワード生成はいろいろ方法があるけど、CORE SERVERのコントロールパネルから「ツール」=>「htpasswdの生成」でフォームを入力するとテキストが出てくるので、それをコピーして、認証をかけたいディレクトリに「.htpasswd」というファイルを作成して貼り付ける。「name:aisrVYJBuecKI」こんな感じのテキストです。

例えば、shinjuku_pg.com というサイト全体に認証をかけたい場合、

「/virtual/USERNAME/public_html/shinjuku_pg/.htpasswd」にファイルを作成する。「USERNAME」は自分ユーザー名に置き換えてください。

コントロールパネルのファイルマネージャからだと。USERNAMEまで省略されて表示されるので、「/public_html/shinjuku_pg/.htpasswd」ですね。

次に、.htaccessファイルを作成。

上のパスワードファイルと同じ場所に「.htaccess」というファイルを作成。

下記内容を書き込む。

order deny,allow

deny from all

allow from 123.456.789.001

allow from 123.456.789.002

AuthUserFile /virtual/USERNAME/public_html/DOMAIN.COM/.htpasswd

AuthGroupFile /dev/null

AuthName "Contact me!@shinjuku_pg"

AuthType Basic

require valid-user

allow from 123.456.789.001

IP部分は許可したいIPに書き換える。複数のIPを許可したい場合は、alow~の行を複数書けばよい。

「USERNAME」は自分ユーザー名に置き換えてください。

「DOMAIN.COM」は制限したいドメイン名もしくはディレクトリです。

「AuthName」の項目は好きに書いてokです。

これだけで、許可したIPアドレスからしかアクセスができなくなります。許可IPからでもパスワードが必要です。

個人的にはこんな設定が必要になることなんてあり得ないんですけどね。

セキュリティ的にbasic認証なんて気休めだけど、core serverはdigest認証使えなかった気がするし仕方ないのか。せめて共有SSL使わないと。

安いサーバセキュリティ求められてもムリですし。

2011-03-15

Zend_DateでTwitterの日付を整形・変換

Twitterの日付フォーマットはZend_Dateでは「"EEE MMM dd HH:mm:ss Z YYYY"」となっているはずなのだが、上手くいかない。

めんどくさいので、Zend_Dateのバグと言う事にして回避策を講じてみた。

$response->created_at = "Mon Mar 14 10:27:05 +0000 2011"

$date = new Zend_Date(strtotime($response->created_at));
print_r($date->toArray());

Array
(
    [day] => 14
    [month] => 3
    [year] => 2011
    [hour] => 19
    [minute] => 27
    [second] => 05
    [timezone] => JST
    [timestamp] => 1300098425
    [weekday] => 1
    [dayofyear] => 72
    [week] => 11
    [gmtsecs] => 32400
)

とりあえず、strtotimeが優秀で、誤変換なども今のところなく動いている。

言ってしまえば、Zend_Dateを使う意味が全く無いのだが・・・

ちなみに、本来ならきっと動くはずのZend_Dateを使ったやり方。

間違いがあったら、是非ご教授頂きたいです。

$date = new Zend_Date($response->created_at, "EEE MMM dd HH:mm:ss Z YYYY");
print_r($date->toArray());

Array
(
    [day] => 14
    [month] => 3
    [year] => 0
    [hour] => 10
    [minute] => 27
    [second] => 05
    [timezone] => JST
    [timestamp] => -62161047175
    [weekday] => 5
    [dayofyear] => 73
    [week] => 11
    [gmtsecs] => 0
)

ご覧の通り、yearの判別が上手くいかないです。

2011-01-27

MacローカルのZendFrameworkとNetBeansでコマンドラインツールが動かないときの対処

Warning: include_once(NetBeansCommandsProvider.php): failed to open stream: No such file or directory in /usr/local/zend/share/ZendFramework/library/Zend/Loader.php on line 146

コマンドラインでzfコマンドを使ったらこんなエラーが発生した。

たぶん、NetBeansZend Frameworkの設定をした時のみ発生すると思われる。

結論から言うと、ZendFFのバグで.zf.iniを修正することで回避できる。

$ vim ~/.zf.ini 

コマンドラインツールの設定を編集

php.includepath = "/Applications/NetBeans/NetBeans 6.9.1.app/Contents/Resources/NetBeans/php/zend:.:/usr/local/zend/share/ZendFramework/library:/usr/local/zend/share/pear"

上記のような内容になってるはずなので、以下の様に修正。

php.include_path = "/Applications/NetBeans/NetBeans 6.9.1.app/Contents/Resources/NetBeans/php/zend:.:/usr/local/zend/share/ZendFramework/library:/usr/local/zend/share/pear"

冒頭のphp.includepathをphp.include_pathに治すだけです。

これで、

$ zf show version
Zend Framework Version: 1.10.1

こんな風にちゃんと動きます。

ソースはこちら。

https://netbeans.org/bugzilla/show_bug.cgi?format=multiple&id=187234

2010-03-08 パソコンの未来 自分がパソコンに求める物

パソコンの未来 自分がパソコンに求める物

chrome OSなどが出てきて、想像が膨らむパソコン未来

今回はWebのこっち側について考えてみる。

chrome OSは全てをWebのあっち側に持って行こうとしているとして、じゃあ、今こっち側に必要な物は何か。

まず、パソコンという箱があり、それがパソコンとして起動することは大前提だ。それにはwinは必要なくmacOSでもlinuxでも何でも良い。

パソコンが起動されて、次に必要な物はwebブラウザ。これは現状chrome一つでOKだと思う。

ブラウザ以外で今使用している自分パソコンに入っているアプリケーションを見渡すと、サーバとのファイルのやりとりを行うftp系のツールだけは必要に感じた。それとプログラマとして開発環境はなくてはならない。

まずは、ftpによるサーバとのファイル操作について考えてみる。

私の場合、仕事でも趣味でもローカルファイルをsftpでサーバにアップするという作業を頻繁に行う。ファイルというのは主にプログラミングソースだ。また、ローカルソースファイルは全てWeb上のSVNに上げている。これはバックアップというよりも、メインはSVNにあると思っている。つまりローカルにチェックアウトしたファイルは作業用の一時的な物で、いつ消えても構わない。

なので、環境が変わっても(違うパソコンからでも)常に同じ作業を行うことができる。

一度SVNからローカルソースを落とし、修正しローカルで動作チェックを行い、サーバにアップして、SVNにも反映させる。

そんな作業になっている。

この一連の作業は、SVNから直接サービスを公開しているサーバファイルをアップする事で改善できる。

具体的には、SVNコミットした時点でWeb上にあるステージング環境自動反映させる。検証に問題がなければ、ステージングのファイル群を公開環境に反映させる。これはrsyncとかでカンタンに実現できる。

これによりローカルwebとの接点は「SVN<−>ローカル」のみに絞られる。さらに細分化すると、SVNからのチェックアウト(若しくはアップデート)とSVNへのコミットの二つになる。

途中でsshなどによる作業も入るが、これは適当なスクリプトを作るだけでWebから行える。更にいえば、Webからssh接続を行うこともカンタンにできる。

これで一つ目のftpツールの問題は解決された。

続いて開発環境について考えてみたいと思う。

まず、自分の開発環境について定義をしておく。

私の場合、全てWebアプリケーションの開発だ。言語で言えば、phphtmlcssjavascriptといった具合。たまにpythonとかperlも使うがここでは割愛。

プログラミングに使用するエディターはすべてeclipseになっている。たまに軽量なエディターも使用するが、なくてもいいのでこれまた省く事とする。

ローカルPC内にもサーバを立ち上げ動作検証を行うので、apacheやらphpやらMySQLなどその辺のものも一式入っている。

後は、動作検証用のブラウザコマンドラインからphpを動かしたりするときのターミナルが必要。

なくても良いが使っているものとし、DB設計にMySQLworkbenchなども上げられる。ほかの仕様書などのドキュメント系はほぼWebプロジェクト管理ツール内にあるwiki制作しているが、一応オフィスexcelwordも必要なツールとして数えておこう。

こんな感じの開発環境となっている。

さっそくこれらをWebに移行する事を考えてみる。

まずは消去法で。

ローカルサーバ環境は全てあっち側に持って行ける。言うまでもないので細かい事は省略して、可能だということにしておく。

続いて、ブラウザも言うまでもなく、PCとして必要な物なのでパス。コマンドラインは前述したが、なんとでも代用がきく。

DB設計はなくてもいいし、WWW SQL Designerで代用もきく。

excelwordGoogleドキュメントで問題なし。もともとドキュメント系はweb上のwikiなので移行もスムーズだし、一元化できた方が能率的かつ管理も楽だ。

残るはエディターであるeclipseエディターといっても、この中にはSVNデバッガーも含まれる。Webに移行すると言うことでSVNは外してしまってもいいだろう。デバッガーはなくても何とかなる、、、はず。

なので、エディターとしての機能のみ考えていく。

php開発を行っている人で、エディターは秀丸だけ、とかvi系だけで行っている人もいるが、eclipseの補完機能とか、ホバーによる関数へのリンクとか、構文エラー自動検知とか、絶対にあると作業効率が格段に増す機能はなくてはならない。使わない人の気が知れないぐらい依存している。

つまり、必要なのはweb上で使用でき、eclipse並みの高機能なエディターだ。むしろeclipseweb上で使えることと言ってしまってもいいだろう。

残念ながら、今のところこれらのeclipseの機能はWeb上では無理だろう。作ることはできるとしても、動作が遅かったら意味がない。

不可能という言葉でこの問題解決は締めくくられてしまった。

仕方ないので、秀丸程度の機能が使えるweb上のエディターで代用ができることに無理矢理考え方を変えて、考察を続行することにした。

とりあえず、あることはある。

http://phpanywhere.net/

http://0-oo.net/sbox/web-editor

このあたり。

あとは、emacs。これはプラグインがたくさんあるから大概の機能は揃うはず。使ったことないので、なんとも、、、

ただ間違いなくマウスが使えない事は自分にとって最大のデメリットになる。コマンドラインでは複数のファイル編集もできないし。ターミナルを複数立ち上げるとか?何か違うそれは。

emacsを使う前提だと既存Webブラウザでは少し厳しいのではと思う。専用のターミナルで、複数タブや画面分割、複数の画面を一つのウインドウに表示するなど、犠牲にしかねる機能がある。要はpoderosa並みの機能が欲しい。まぁ理想として置いておく。

開発環境に関してはかなり多くの妥協に次ぐ妥協を重ねた結果、Web上若しくはサーバ側で動きターミナルで操作できるツールで代用ができそうだと結果に。

エディターに関しては私と同じような考え方をする人の需要が増えてこれば、きっと私が納得できるアプリケーションが作られると思う。

漠然としたイメージだと、emacsの機能をブラウザ上でグラフィカルに表示できて、軽快さが保たれればいいのだから、可能性はいくらでもあると思う。まぁあくまでphpなどのWeb言語に限った話だが。

ローカルに一切のファイルを置かず、全てあっち側で管理する。どうしても実ファイルが必要な場合は、S3とかDropBoxとかクラウド系のサービスを使う。もっと言えば、自分専用のクラウドサーバを用意しその中に全部放り込む。管理はGoogleデスクトップとかでもインストールしておけばいろいろできると思われ。

基本的な作業で必要なファイルは、wikiGoogleドキュメントSubversionで管理するのがベストだと思う。

開発に関しては、ソースSubversionで管理。何か作るときはサーバ上でSubversionからチェックアウトし、サーバ上でブラウザターミナルから作業を行う。このサーバテスト環境も構築できていれば検証もここで完結することにもなる。チェックアウト先をそのままapacheの公開Dirとしておけばよい。(※セキュリティーの問題はIP指定とかで回避ということで)

作業が終わったファイルSVNコミットし、コミットされたファイル自動的にステージング環境rsyncでアップされる。

ステージング環境の変更を本番に反映するのもftpなど使わずにrsyncで同期する。

データバックアップなども全てサーバ間で行う。

ファイルダウンロードなどを行う時は、ローカルダウンロードせず直接サーバダウンロードというかアップロードを行うこともできるはず。

mobile me(iDisk)などのようにサーバにあるディレクトリローカルにあるように見せることもできるし可能だろう。どういう仕組みかわからないが、iDiskローカルに実ファイルダウンロードされないのにとっても高速に接続できる。

DropBoxなどでも似たような事ができるかもしれない。

VNPとかで、サーバ上のsambaに接続するだけでも十分かもしれない。


かもしれない、とか〜だと思う、といた表現がやたら多くなったが、一応結論として現時点でもローカルデータを全てweb上に移行することが可能だ。

ただし、それには多少の犠牲を伴うが、これは時とともに解決されて行くであろう問題で、理想環境がより早く実現するために私はこれからクラウド化を率先して取り入れて行く事にする。


ここでもう一つ問題定義だけしておく。

クラウドが台頭してきた理由にネットワークの高速がある。

これに対し今後、記憶媒体の大容量化+安価化が想像だにしない速度で進んだ場合、今のクラウド化と正反対の現象が起きる可能性もあるのではないか。

極端な例を挙げると、web上の全ての情報ローカルPCの中に保存する事が出来るようになるかもしれない。

更にパソコンネットワークの高性能化が進んだ場合、サーバを必要としなくなる事も考えられる。

数日間充電する必要のない電池ができ、パソコンそのものの飛躍的な性能アップ、WiFiMaxのような無線技術革新が起きるとする。

するとパソコンを一つ持ち歩くだけで、常に全ての情報を蓄積し、そのパソコンから常に自分情報も発信する。こうなると余程の膨大なトラフィックがあるサイトで無い限り、サーバの必要性はなくなるかもしれない。

そんな未来も見てみたいものです。

2009-09-23 初めてのsymfony〜PEARインストール編

初めてのsymfony〜PEARインストール編パート2

実践編もパート2を迎えいよいよクライマックスの3っつ前ぐらいです。

symfonyで動くものを作ってみるお話。


では早速動くものを作っていくとします。

Hello World?何それ?時間の無駄です。

というより、とりあえず表示させるだけも、動くものを作るのもあまり時間はかわらない。しかし!理解は数百倍深まるので、いきなり動くものを作る。これ真理かも。


ここからプロジェクトディレクトリにいるとして、相対パスで書いていきます。

ちなみに私は、すべてターミナルから作業しました。(ホントです)


さてさて、モジュールを生成から。

symfony init-module myapp mymodule

もう慣れたと思いますが、上のコマンドだけでモジュールのひな形が自動生成されます。

ここで、htaccessの設定を行います。

すでに、web以下に自動生成されているものを修正します。

少し余分な設定があるので、以下の行を残して残りの設定をコメントアウトします。

web/.htaccess

RewriteCond %{REQUEST_FILENAME} !-f

RewriteRule ^(.*)$ index.php [QSA,L]

http://symfony.localserver/mymodule

ここにアクセスすると、moduleなんとかsuccess!と表示されるはずです。

これでモジュールができました!


ここでは簡単な投稿システムを作りながら、symfonyのすごさを体感しましょう。

symfony」でデータベースを生成してテーブルを作ります。

CREATE TABLE `posts` (
  `id` int(11) NOT NULL auto_increment,
  `title` varchar(255) NOT NULL,
  `text` text NOT NULL,
  `modified` timestamp NULL default CURRENT_TIMESTAMP,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

手抜きですみません。。。

DBの設定をyaml記述します。

yamlの事はすっ飛ばしますが、インデットが命です!解らない人は、必ず正確にコピペ職人に徹しましょう。

スキーマの設定。まぁテーブルの設定と言うことで。

config/schema.yml

propel:
  posts :
    _attributes: { phpName: Post }
    id:
    title:       varchar(255)
    text:        longvarchar
    modified: timestamp

DBの基本設定です。

config/databases.yml

all:
  propel:
    class:          sfPropelDatabase
    param:
      phptype:      mysql
      hostspec:     localhost
      database:     symfony
      username:     symfony_user
      password:     secret_pass

DBモデルを生成します。これまた自動です。cache削除を忘れずに。

symfony propel-build-model
symfony clear-cache

キャッシュ削除と書きましたが、symfonyではyamlの設定とか、クラスファイルの場所とか、なんでもキャッシュ化しているので、ちょっと変更するたびにキャッシュをクリアする必要があるんですね。


次にコントローラを修正します。

apps/myapp/modules/mymodule/actions/actions.class.php

executeIndex内のforwardを行っている行をコメントアウトします。

さぁこれで、もう一度さっきのURLアクセス

http://symfony.localserver/mymodule

何が表示されましたか?

何も表示されない??そうす!それが正解です。

forwardして表示されていたさっきのsymfony画面が、コメントアウトしたことで表示されなくなったのです。

続いて、templateを修正しましょう。

apps/myapp/modules/mymodule/templates/indexSuccess.php

ここにてきとーに「Hello Worl」とでも入力して、mymoduleに再びアクセスしましょう。

ちゃんと入力した内容が表示されていますね。

ここで、表示された画面のソースを見てみましょう。

そうです!htmlのヘッダが出力されています。

symfonyでは最初からレイアウト構造ができているのです。いやー便利ですねー。


つーか、「Hello World!」やんないとか言っておきながら、、、


長くなったのでここから一気です。

ファイルを以下の様に修正、及び新規作成します。

apps/myapp/modules/mymodule/actions/actions.class.php

<?php

/**
 * mymodule actions.
 *
 * @package    myproject
 * @subpackage mymodule
 * @author     Your name here
 * @version    SVN: $Id: actions.class.php 2692 2006-11-15 21:03:55Z fabien $
 */
class mymoduleActions extends sfActions
{
  /**
   * Executes index action
   *
   */
  public function executeIndex()
  {
    //$this->forward('default', 'module');
        $posts = PostPeer::doSelect(new Criteria());
        $this->posts = array();
        foreach ($posts as $post) {
                $this->posts[] = array(
                        'id' => $post->getId(),
                        'title' => $post->getTitle(),
                        'modified' => $post->getModified() ,
                );
        }
  }

  public function executeRead()
  {
    $id = (int) $this->getRequestParameter('id');
        $post = PostPeer::retrieveByPk($id);
        if ($post) {
                $this->title = $post->getTitle();
                $this->text = $post->getText();
        }
  }
  public function executeWrite()
  {
        $this->title = $this->getRequestParameter('title');
        $this->text = $this->getRequestParameter('text');
        if ( $this->title && $this->text) {
                $post = new Post();
                $post->setTitle($this->title);
                $post->setText($this->text);
                $post->save();
                $this->id = $post->getId();
        }
}

apps/myapp/modules/mymodule/templates/indexSuccess.php

<h2><?php echo link_to("It's BLAHG!",'mymodule/index') ?></h2>
<table>
<tr>
<th>Title</th>
<th>Last Modified</th>
<?php foreach ($posts as $post) { ?>
        <tr>
        <td><a href='mymodule/read/id/<?php echo $post['id'] ?>'><?php echo $post['title'] ?></a></td>
        <td><?php echo $post['modified'] ?></td>
        </tr>
<?php } ?>
</table>
<h4><?php echo link_to('write','mymodule/write') ?></h4>

apps/myapp/modules/mymodule/templates/readSuccess.php

<h2><?php echo link_to("It's BLAHG!",'mymodule/index') ?></h2>
<?php if (isset($title)) { ?>
<h4><?php echo $title ?></h4>
<pre>
<?php echo $text ?>
</pre>
<?php } else { ?>
<h4>Post not found</h4>
<?php } ?>

apps/myapp/modules/mymodule/templates/writeSuccess.php

<h2><?php echo link_to("It's BLAHG!",'mymodule/index') ?></h2>
<?php if (isset($id)) { ?>
<h4>Post Submitted.  <a href='read/id/<?php echo $id?>'>view post</a>
<?php } else { ?>
<?php echo form_tag('mymodule/write') ?>
<table>
<tr>
        <tr>
                <td><?php echo label_for('title', 'title') ?></td><td><?php echo input_tag('title') ?></td>
        </tr>
        <tr>
                <td /><td><?php echo textarea_tag('text') ?></td>
        </tr>
        <tr>
                <td /><td><?php echo submit_tag('submit') ?></td>
        </tr>
</form>
<?php } ?>
</table>

ここまで書いたら、モジュールアクセスしてみましょう。

ちゃんと表示されていますね。

writeから投稿画面に入って、適当に入力して登録してみて下さい。

TOPに戻ると、登録した内容がちゃんと表示されているはずです。


一気に書いた内容も特に難しい事はないですよね?読めば何となくは意味がつかめるはずです。


1つ言わせてもらうと、DBクラスは素晴らしいですね。ここまで簡素化してるなんて。ZendFrameworkよりも、シンプルで分かりやすい。ここまで可読性が高いのにやってることはとっても高度な感じします。まぁあくまで、基本的な動作を見ただけの感想ですが。

これで見事ブログみたいな投稿機能が実装されました。

「こんな簡単にできるの!?」と思うか、「これだけやって、たったこんだけの内容!?」って思うかは人それぞれですが、symfonyのすごさはまだまだここからだったりします。

次回はこれをベースに高機能ブログモジュールを作っていきます!

次回、symfony実践編パート3。You can advance?

お楽しみに。


※この記事は、私の大嫌いなIBM様の「PHPフレームワーク」の連載を大いに参考にさせて頂いています。

http://www.ibm.com/developerworks/jp/views/opensource/libraryview.jsp?search_by=PHP+フレームワーク

symfonyのヴァージョンも変わってるせいか、ぼろぼろなのであまり見る価値ないかもです。

初めてのsymfony〜symfony実践編

連載もとうとう第三回!

今回は、symfony実践編。

symfonyプロジェクトアプリケーションを作っていくお話。

symfonyプロジェクトアプリケーション

プロジェクト製作

mkdir /var/www/myproject
cd /var/www/myproject
symfony init-project myproject

アプリケーションのセットアップ

symfony init-app myapp

これで、appsの下にmyappが作成された。


次に、apacheの設定で今回は完了です。

<VirtualHost *:80>

DocumentRoot /var/www/myproject/web

ServerName symfony.localserver

ServerAlias symfony.localserver

ErrorLog logs/symfony_error_log

CustomLog logs/symfony_log common

</VirtualHost>

クライアントのhostsに「symfony.localserver」とIPマッピングをして、アクセスすると、「Symfony Project Created」って表示されるよ。

このままだと、画像リンクが切れた状態で表示される。

別に気にしなくとも良いのだが、デバッグとかでも使うのでエイリアスも追加しておく。

上のアパッチの設定のVirtualHostの中に

Alias /sf /usr/share/php/PEAR/data/symfony/web/sf

と1行入れておく。

これでsymfonyのdataにある画像cssリンクが繋がる。

htaccessを有効にしたり、アクセス権に問題があるのなら、以下をDIRの設定に追加。

AllowOverride All

Allow from All

ここまでやればバッチリ表示されるだろう。

また、デバッグ用の表示を行いたいなら、こっちにアクセスしてみよう。いろいろな情報を表示させることができる。

これは、アプリケーションを作ってからも使えるので忘れないでメモ。

http://symfony.localserver/myapp_dev.php

そろそろsymfonyのスゴサが見え隠れしてきましたね。

でもまだまだ、ここからが感動の嵐です。

さて、次回はなんと、いきなり動くものを作っていきます!symfony実践編パート2。混沌の先に見えるは光か闇かー

お楽しみに。

初めてのsymfony〜symfonyインストール編

PEARを使ってsymfonyを簡単インストールするお話。


PEARにchannellを追加して、インストール実行

# pear channel-discover pear.symfony-project.com
# pear remote-list -c symfony
# pear install symfony/symfony
# pear install http://phing.info/pear/phing-current.tgz

これで完了。続いてsymfonyコマンドシンボリックリンクをつける。

# ln -s /usr/share/php/bin/symfony /usr/bin/symfony

これで、

# symfony -T

コマンド情報が表示されればOK。

いやー簡単ですね。

さて、次回はいよいよsymfonyアプリケーションを作っていきます!symfony実践編。

お楽しみに。

イントラのサーバsymfonyインストールする時のお話。

第一回、PEARインストール

symfonyインストール方法はいろいろあるが、一番簡単なPEARを使う方法で説明します。

実際に作業を行った環境はfedora11です。

ディレクトリとかは標準的だと思います。

PEARインストール

/usr/share/php/

以下にインストール

$ curl http://pear.php.net/go-pear > go-pear.php
# php -q go-pear

設定を少し変更。

1. Installation prefix ($prefix) : /usr/share/php

# /usr/share/php/bin/pear

動作を確認。

# ln -s /usr/share/php/bin/pear /usr/bin/pear

/user/binにリンクを張って、pearコマンドを有効にする。

これで、pearを直接たたける様になるのです。

さて、次回はいよいよ大詰め!symfonyインストール編。

お楽しみに。