phpのフレームワークsymfonyのsfPropelPagerクラスのgetLinksメソッドに引数を設定出来る事を知りました。
PEAR::Pagerだと、Pager::factory() メソッドのdeltaオプションで、現在のページの前後に表示するページ番号の個数を指定する事が出来るのですが、symfony1.0.19のsfPropelPagerのgetLinksメソッドに関しての情報が全然無くて、前後に表示されるページ番号の個数を変更する方法がわかりませんでした。
どうにか出来ないものかと/usr/share/pear/symfony/addon/sfPager.class.phpのgetLinksメソッドを見てみると、下記のような記述になっていました。
public function getLinks($nb_links = 5)
getLinksメソッドの$nb_links変数に数値を渡す事で、前後に表示されるページ番号の数が調節出来るのを確認出来ました。
下記は使用例です。
<?php $links = $pager->getLinks(10); foreach ($links as $page): ?> <?php echo ($page == $pager->getPage()) ? $page : link_to($page, 'search', array('query_string' => 'page='.$page."&".$link)) ?> <?php endforeach ?>
[PR]Spreeの情報を集めています。
ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/
phpのSnoopy+htmlSQLでスクレイピングする時、POSTメソッドでhttpリクエスト出来ない対処方法。
phpのSnoopyライブラリはPEAR::HTTP_Requestと同じようなライブラリなのですが、HTTPリクエスト後、スクレイピングする処理は様々な方法があるようです。
http://saboten009.blogspot.com/2008/08/php.html
僕は使用した事が無いのですが、Tidy関数を利用すると上手くスクレイピング出来るという記事を良く目にするのですが、導入の仕方がどうもわからなくて他の方法を探していました。
色々検索すると、Snoopy+htmlSQLでもスクレイピング出来て、
require_once("Snoopy.class.php"); require_once("htmlsql.class.php");
だけで使用出来るので、実際に使ってみました。
下記の本家のサイトにデモがあります。
http://www.jonasjohn.de/lab/htmlsql.htm
SQLを書くようにHTMLをスクレイピング出来るので面白いなーと思っていたのですが、HTTPリクエストのPOSTメソッドが利用出来ないという事に気づきました。(Snoopy単体だと出来るんですけどね…)
POSTでHTTPリクエストしたかったので、自分でhtmlsql.class.phpを修正しました。
htmlsql.class.phpの$varsプロパティの追加
var $vars = '';//90行目辺りに追加
htmlsql.class.phpのconnectメソッドの修正
function connect($type, $resource, $method='get'){ if ($type == 'url'){ if($method == 'post'){ return $this->_fetch_url($resource, 'post'); } else { return $this->_fetch_url($resource, 'get'); } } else if ($type == 'file') { if (!file_exists($resource)){ $this->error = 'The given file "'.$resource.' does not exist!'; return false; } $this->page = file_get_contents($resource); return true; } else if ($type == 'string') { $this->page = $resource; return true; } return false; }
htmlsql.class.phpの_fetch_urlメソッドの修正
function _fetch_url($url, $method){ $parsed_url = parse_url($url); if (!isset($parsed_url['scheme']) or $parsed_url['scheme'] != 'http'){ $this->error = 'Unsupported URL sheme given, please just use "HTTP".'; return false; } if (!isset($parsed_url['host']) or $parsed_url['host'] == ''){ $this->error = 'Invalid URL given!'; return false; } $host = $parsed_url['host']; $host .= (isset($parsed_url['port']) and !empty($parsed_url['port'])) ? ':'.$parsed_url['port'] : ''; $path = (isset($parsed_url['path']) and !empty($parsed_url['path'])) ? $parsed_url['path'] : '/'; $path .= (isset($parsed_url['query']) and !empty($parsed_url['query'])) ? '?'.$parsed_url['query'] : ''; $url = 'http://' . $host . $path; $this->init_snoopy(); if($this->snoopy->fetch($url) && $method == 'get'){ $this->page = $this->snoopy->results; // empty buffer: $this->snoopy->results = ''; } else if($this->snoopy->submit($url, $this->vars) && $method == 'post'){ $this->page = $this->snoopy->results; // empty buffer: $this->snoopy->results = ''; } else { $this->error = 'Could not establish a connection to the given URL!'; return false; } return true; }
下記が呼出しの例です。
$wsql = new htmlsql(); $wsql->vars['page'] = $i;//POSTしたいデータの例 $wsql->connect('url', 'http://d.hatena.ne.jp/camelmasa/', 'post');//第3引数に"post"と書けばPOSTメソッドで通信します。
htmlsqlを使用する人はあまりいないかあ。
こうゆう事ってperlの方が得意そう。
最近のスクレイピング技術ってどうやってるんだろう?
Xpath?
[PR]Spreeの情報を集めています。
ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/
Oracle Application ExpressとphpMyAdminのインストール方法を比較しました。
Oracle Database XEの場合、Oracle Application Expressが自動的にインストールされるので、GUIでの管理ツールに困る事はありません。
しかし、MySQLの場合管理ツールが提供されていないので、phpMyAdminというOSSをインストールして使用します。(一番有名かな?)
インストール方法は、まずphpMyAdminのサイトでダウンロードします。
(php,php-mysqlのパッケージがインストールされている必要があります。)
phpMyAdmin
http://www.phpmyadmin.net/home_page/ownloads.php
一度ローカルにダウンロードしてサーバーにアップロードするのも良いのですが、サーバーから直接ダウンロードする方が楽です。
cd /var/www/html wget http://nchc.dl.sourceforge.net/sourceforge/phpmyadmin/phpMyAdmin-2.11.9.4-all-languages.zip
次に解凍、ディレクトリ名の変更、zipファイルの削除をします。
unzip phpMyAdmin-2.11.9.4-all-languages.zip mv phpMyAdmin-2.11.9.4-all-languages phpMyAdmin rm -f phpMyAdmin-2.11.9.4-all-languages.zip
次にconfigファイルを編集します。
cd phpMyAdmin mv config.sample.inc.php config.inc.php vi config.inc.php $cfg['blowfish_secret'] = ''; ↓ $cfg['blowfish_secret'] = '任意の文字列';
ブラウザからアクセスします。
http://192.168.11.3/phpMyAdmin/
下記に”mcrypt拡張をロードできません”という記述がある場合、php-mcryptのパッケージをインストールすることをお薦めします。
php-mcryptのパッケージをインストールすると下記のような画面になります。
これがphpMyAdminのインストール方法です。
(先月から下書き眠らせてあったのですが、別に眠らせなくても良いかと思って記事にしました。)
[PR]Spreeの情報を集めています。
ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/
Oracle Database XEをphpからCRUD(CREATE,READ,UPDATE,DELETE)を実行しました。
Oracle Database XEをphpから実行する為に色々調べました。
標準関数で出来ないかなと探したのですが、なかなか見つからず…。
OTNのZend Core for Oracleというのをインストールしてみたのですが、インストールに失敗してphp.iniがおかしな事になってしまいました!
php.iniのバックアップしておけば良かったと後悔。(php5.2.6になってるし…)
ZendCoreについて
http://www.oracle.com/technology/tech/php/zendcore/index.html
結局元に戻す方法がわからなかったので、OSからインストール。
その後、Oracle Database XEをインストールし直しました。
http://www.oracle.com/technology/global/jp/tech/php/htdocs/php-oracle-tutorial.html
上記のチュートリアルに紹介されているoci8関数をインストールしても、oracleへ接続出来そうなので、
peclでoci8関数をインストールしました。
pecl install oci8
oci8関数をインストール後、phpから利用する為に、
php.iniにextension=oci8.soを追加しapacheを再起動しました。
/var/www/html/test.phpを作成。(チュートリアル丸写し)
<?php $conn = oci_connect('hr', 'hrpw', '//localhost/XE'); $stid = oci_parse($conn, 'select city from locations'); oci_execute($stid); print '<table border="1">'; while ($row = oci_fetch_array($stid, OCI_RETURN_NULLS)) { print '<tr>'; foreach ($row as $item) { print '<td>'.($item?htmlentities($item):' ').'</td>'; } print '</tr>'; } print '</table>'; ?>
コマンドラインから実行すると、
環境変数ORACLE_HOMEの値がないというエラーが表示されました。
php test.php PHP Warning: oci_connect(): OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME is set and points to the right directory in /var/www/html/test.php on line 2 PHP Warning: oci_parse() expects parameter 1 to be resource, boolean given in /var/www/html/test.php on line 4 PHP Warning: oci_execute() expects parameter 1 to be resource, null given in /var/www/html/test.php on line 5
なので.bashrcに以下を記述
. /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/oracle_env.sh source .bashrc
php test.php <table border="1"><tr><td>city1</td><td>city1</td></tr></table>
やっとSQLを実行できました。
しかし、ブラウザからアクセスするとまだ真っ白の画面が表示され、エラーログに下記が記述されていました。
tail /var/log/httpd/error_log [Wed Jan 21 08:44:44 2009] [error] [client 192.168.11.8] PHP Warning: oci_connect() [<a href='function.oci-connect'>function.oci-connect</a>]: OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME is set and points to the right directory in /var/www/html/test.php on line 2 [Wed Jan 21 08:44:44 2009] [error] [client 192.168.11.8] PHP Warning: oci_parse() expects parameter 1 to be resource, boolean given in /var/www/html/test.php on line 5 [Wed Jan 21 08:44:44 2009] [error] [client 192.168.11.8] PHP Warning: oci_execute() expects parameter 1 to be resource, null given in /var/www/html/test.php on line 6 [Wed Jan 21 08:44:44 2009] [error] [client 192.168.11.8] PHP Warning: oci_fetch_array() expects parameter 1 to be resource, null given in /var/www/html/test.php on line 9
apache経由だと環境変数ORACLE_HOMEが定義されていないようです。
かなり強引ですが、/etc/init.d/httpdのstart時に無理やり定義してみました。
vi /etc/init.d/httpd start() { ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server echo -n $"Starting $prog: " check13 || exit 1 LANG=$HTTPD_LANG daemon $httpd $OPTIONS RETVAL=$? echo [ $RETVAL = 0 ] && touch ${lockfile} return $RETVAL }
これでやっとブラウザ経由でSQLを実行する事が確認できました。
[PR]Spreeの情報を集めています。
ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/
phpのZip関数をインストールしました。
仕事でphpのZip関数をインストールしたのでメモ。
Zip関数のインストール方法
http://php.benscom.com/manual/ja/zip.installation.php
方法が2つあるみたいです。
①phpをソースからインストールする時に、zipサポートを有効にしてPHPをコンパイルする方法
②PECL経由でのインストール方法
仕事では②の方法でインストールしました。
まず、PEARの不具合を修正します。
http://d.hatena.ne.jp/snegishi/20071212/1197422664
修正後、php.iniのmemory_limitの値を32Mもしくは64Mに設定します。
その後、下記のpeclコマンドにてZip関数をインストールします。
pecl install zip
Zip関数をインストール後、phpから利用する為に、
php.iniにextension=zip.soを追加しapacheを再起動して
インストールが完了しました。
[PR]Spreeの情報を集めています。
ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/
symfony懇親会に参加しました。
一昨日、株式会社ディノで開催されたsymfony懇親会に参加しました。
http://events.php.gr.jp/events/show/62
インターネットでも書籍でもsymfony1.2系の情報が無いので、symfony1.2系の情報収集方法が知りたくて参加しました。
参加された方に色々聞いてみましたが、現状はソースコードから直接読んだり、本家symfonyのサイト(英語)を読んでいるようです。
英語の読み書きが出来るっていうのは様々な点で得だなーとしみじみ思いました。
少しづつiKnowで勉強していこう。
誰かがsymfony1.2の書籍を作ってくれないかなと期待…。
(アシアル株式会社さん or ディノ株式会社さんお願いします!)
symfony懇親会に参加された中には、面白法人カヤックの方やアシアル株式会社の方も参加されていました。
また、マンモス表紙の『symfony徹底攻略』の著者でもあるおやぢ組の方も参加されていました。
今回懇親会の会場となったビルの5階と7階にディノ株式会社があり、6階にウノウ株式会社があるのを知り驚きました。
技術者が沢山いるビル…。羨ましいですね。
懇親会の場を提供して頂いたディノ株式会社様有難う御座いました。
また懇親会、勉強会が開催される事を期待しています。
関連記事
サイボウズ・ラボの秋元さんの記事
http://akimoto.jp/blog/2008/11/29/symfony%E6%87%87%E8%A6%AA%E4%BC%9A%E3%81%AB%E8%A1%8C%E3%81%A3%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/
『おやぢ組』のid:brtRiverさんの記事
http://d.hatena.ne.jp/brtRiver/20081129/1227961269
[PR]Spreeの情報を集めています。
ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/
php5フレームワークsymfonyを勉強しました。その3
前回の続き。7章を勉強しました。
ビューレイヤーの内側
サンプルのindexSuccess.phpテンプレート
<h1>ようこそ</h1> <p>お帰りなさい、<?php echo $name ?>!</p> <ul>何をなさりたいですか? <li><?php echo link_to('最新の記事を読む', 'article/read') ?></li> <li><?php echo link_to('新しい記事を書き始める', 'article/write') ?></li> </ul>
input_tagヘルパー
<?php echo input_tag('nickname') ?> => <input type="text" name="nickname" id="nickname" value="" />
auto_link_textヘルパー
<?php echo auto_link_text('我々のサイトにお越し下さい www.example.com') ?> => 我々のサイトにお越し下さい <a href="http://www.example.com">www.example.com</a>
ヘルパーを宣言する
// このテンプレート内で特定のヘルパーグループを使う <?php use_helper('Text') ?> ... <h1>説明</h1> <p><?php echo auto_link_text($description) ?></p>
共通のデフォルトのヘルパー
// Helperグループ <?php use_helper('HelperName') ?> <?php use_helper('HelperName1', 'HelperName2', 'HelperName3') ?> // Tagグループ <?php echo tag('input', array('name' => 'foo', 'type' => 'text')) ?> <?php echo tag('input', 'name=foo type=text') ?> // 代替のオプション構文 => <input name="foo" type="text" /> <?php echo content_tag('textarea', 'ダミーの内容', 'name=foo') ?> => <textarea name="foo">ダミーの内容</textarea> // Urlグループ <?php echo link_to('クリックして下さい', 'mymodule/myaction') ?> => <a href="/route/to/myaction">クリックして下さい</a> // ルーティングの設定による // Assetグループ <?php echo image_tag('myimage', 'alt=foo size=200x100') ?> => <img src="/images/myimage.png" alt="foo" width="200" height="100"/> <?php echo javascript_include_tag('myscript') ?> => <script language="JavaScript" type="text/javascript" src="/js/myscript.js"></script> <?php echo stylesheet_tag('style') ?> => <link href="/stylesheets/style.css" media="screen" rel="stylesheet"type="text/css" />
その他ヘルパー
オンラインのAPIドキュメント(http://www.symfony-project.org/api/1_0/)
独自のヘルパーを追加する
ヘルパー関数(HTMLコードを返す通常のPHP関数)はFooBarHelper.phpという名前のファイルに保存されます。FooBarはヘルパーグループの名前です。ファイルをapps/myapp/lib/helper/ディレクトリ(もしくはプロジェクトのlib/フォルダの1つの元で作られたhelper/ディレクトリ)に保存すればインクルードする際にuse_helper('FooBar')ヘルパーによって自動的に見つかります。
テンプレートのショートカット
$sf_context: コンテキスト全体のオブジェクト(sfContextのインスタンス)
$sf_request: リクエストオブジェクト(sfRequestのインスタンス)
$sf_params: リクエストのパラメータ
$sf_user: 現在のユーザーセッションのオブジェクト(sfUserのインスタンス)
// 長いバージョン <?php echo $sf_request->getParameter('total'); ?> // 短いバージョン <?php echo $sf_params->get('total'); ?> // 次のアクションコードと同等 echo $this->getRequestParameter('total');
パーシャルをmymoduleモジュールのテンプレートの中に含める
// myapp/modules/mymodule/templates/_mypartial1.phpパーシャルをインクルードする // テンプレートとパーシャルは同じモジュールにあるので、 // モジュール名を省略できる <?php include_partial('mypartial1') ?> // myapp/modules/foobar/templates/_mypartial2.phpパーシャルをインクルードする // この場合モジュール名は必須 <?php include_partial('foobar/mypartial2') ?> // myapp/templates/_mypartial3.phpパーシャルをインクルードする // 'global'モジュールの一部として見なされる <?php include_partial('global/mypartial3') ?>
mymodule/actions/actions.class.phpの中で、アクションが変数を定義する
class mymoduleActions extends sfActions
{
public function executeIndex()
{
$this->total = 100;
}
}
mymodule/templates/indexSuccess.phpの中で、テンプレートが変数をパーシャルに渡す
<p>Hello, world!</p> <?php include_partial('mypartial', array('mytotal' => $total) ) ?>
mymodule/templates/_mypartial.phpの中で、パーシャルは変数を利用できる
<p>合計: <?php echo $mytotal ?></p>
modules/news/actions/components.class.phpの中で、コンポーネントクラス
class newsComponents extends sfComponents { public function executeHeadlines() { $c = new Criteria(); $c->addDescendingOrderByColumn(NewsPeer::PUBLISHED_AT); $c->setLimit(5); $this->news = NewsPeer::doSelect($c); } }
modules/news/templates/_headlines.phpの中の、パーシャル
<div> <h1>最新のニュース</h1> <ul> <?php foreach($news as $headline): ?> <li> <?php echo $headline->getPublishedAt() ?> <?php echo link_to($headline->getTitle(),'news/show?id='.$headline->getId()) ?> </li> <?php endforeach ?> </ul> </div>
パラメータをコンポーネントとテンプレートに渡す
// コンポーネントへのコール <?php include_component('news', 'headlines', array('foo' => 'bar')) ?> // コンポーネント自身にて echo $this->foo; => 'bar' // _headlines.phpパーシャルにて echo $foo; => 'bar'
'sidebar'スロットをレイアウト内部でインクルードする
div id="sidebar"> <?php if (has_slot('sidebar')): ?> <?php include_slot('sidebar') ?> <?php else: ?> <!-- default sidebar code --> <h1>文脈上の領域</h1> <p>この領域はページのメインの内容と関連したリンクと情報を含みます。</p> <?php endif; ?> </div>
サンプルのモジュールレベルのview.yml
editSuccess: metas: title: プロファイルを編集する editError: metas: title: プロファイルを編集している間に発生したエラー all: stylesheets: [my_style] metas: title: 私のウェブサイト
apps/myapp/config/view.ymlの中の、アプリケーションレベルのビューのデフォルト設定
default: http_metas: content-type: text/html metas: title: symfony project robots: index, follow description: symfony project keywords: symfony, project language: en stylesheets: [main] javascripts: [ ] has_layout: on layout: layout
アクションはsfResponseオブジェクトメソッドにアクセスできる
class mymoduleActions extends sfActions { public function executeIndex() { $response = $this->getResponse(); // HTTPヘッダー $response->setContentType('text/xml'); $response->setHttpHeader('Content-Language', 'en'); $response->setStatusCode(403); $response->addVaryHttpHeader('Accept-Language'); $response->addCacheControlHttpHeader('no-cache'); // クッキー $response->setCookie($name, $content, $expire, $path, $domain); // メタ情報とページのヘッダー $response->addMeta('robots', 'NONE'); $response->addMeta('keywords', 'foo bar'); $response->setTitle('My FooBar Page'); $response->addStyleSheet('custom_style'); $response->addJavaScript('custom_behavior'); } }
view.ymlの中の「キー: 値」の組としてのメタの定義
http_metas: cache-control: public metas: description: Finance in France keywords: finance, France
レスポンスアクションのレスポンス設定としてのメタの定義
$this->getResponse()->addHttpMeta('cache-control', 'public'); $this->getResponse()->addMeta('description', 'Finance in France'); $this->getResponse()->addMeta('keywords', 'finance, France');
view.ymlの中のタイトルの定義
indexSuccess: metas: title: 3匹の子豚
アクションの中のタイトルの定義 -- 動的なタイトルを可能にする
$this->getResponse()->setTitle(sprintf('%d匹の子豚', $number));
view.ymlの中で、ファイルをインクルードする
indexSuccess: stylesheets: [mystyle1, mystyle2] javascripts: [myscript]
ファイルをアクション内部でインクルードする
$this->getResponse()->addStylesheet('mystyle1'); $this->getResponse()->addStylesheet('mystyle2'); $this->getResponse()->addJavascript('myscript');
アクション内部でメディアを指定したスタイルシートをインクルードする
$this->getResponse()->addStylesheet('paper', '', array('media' => 'print'));
view.ymlの中のレイアウトの定義
indexSuccess: layout: my_layout
アクション内部のレイアウトの定義
$this->setLayout('my_layout');
view.ymlの中でレイアウトの除外
indexSuccess: has_layout: false
アクションの中でレイアウトの除外
$this->setLayout(false);
'sidebar'という名前のコンポーネントをインクルードする
<div id="sidebar"> <?php include_component_slot('sidebar') ?> </div>
myapp/config/view.ymlの中で、デフォルトの'sidebar'スロットコンポーネントを定義する
default: components: sidebar: [bar, default]
myapp/modules/user/config/view.ymlの中で、'sidebar'スロットコンポーネントを特化する
all: components: sidebar: [bar, user]
modules/bar/actions/components.class.phpの中で、'sidebar'スロットによって使用されるコンポーネント
class barComponents extends sfComponents { public function executeDefault() { } public function executeUser() { $this->current_user = $this->getUser()->getCurrentUser(); $c = new Criteria(); $c->add(ArticlePeer::AUTHOR_ID, $this->current_user->getId()); $this->nb_articles = ArticlePeer::doCount($c); } }
modules/bar/templates/の中で、'sidebar'スロットコンポーネントによって使用されるパーシャル
// _default.php <p>この領域はコンテキスト上の情報を含みます。</p> // _user.php <p>ユーザー名: <?php echo $current_user->getName() ?></p> <p><?php echo $nb_articles ?> articles published</p>
view.ymlの中でコンポーネントスロットを無効にする
all: components: sidebar: []
myapp/config/settings.ymlの中で、出力エスケーピング機能を有効にする
all: .settings: escaping_strategy: both escaping_method: ESC_ENTITIES
生のデータを出力することが必要なとき、getRaw()メソッドを呼び出します。
echo $sf_data->getRaw('test'); => <script>alert(document.cookie)</script>
[PR]Spreeの情報を集めています。
ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/