【PHP】Ethna part.2【国産フレームワーク】
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2007/08/03(金) 08:15:18ID:BNMV6wHxEthna -PHPウェブアプリケーションフレームワーク-
http://ethna.jp/
SourceForge.jp: Project Info - Ethna
http://sourceforge.jp/projects/ethna/
クラスドキュメント(phpDocumentor)
http://ethna.jp/doc/
前スレ
【PHPフレームワーク】Ethna【スケルトン自動作成】
http://pc11.2ch.net/test/read.cgi/php/1123070439/
0002nobodyさん
2007/08/03(金) 08:22:09ID:BNMV6wHxA. LLフレームワーク本と同じ内容のモノがここに。
http://labs.gree.jp/Top/Document/20060707.html
Q. CSRFとかの対策は?
A. プラグインが同梱されてる。自動でやっちゃう方法もあるよ(by haltタソ)
http://project-p.jp/halt/anubis/blog_show/645
Q. 何これ、EUC-JPなの?
A. 特定のプロジェクトだけ他の文字コードにしたいなら
http://d.hatena.ne.jp/riaf/20070627/1182941891
EthnaをまるごとUTF-8で使いたいなら
http://blog.c--v.net/2007/07/16/1
Q. ActionFormを書くのがかったるい
A. http://as-roma.com/ethna/formBuilder/
0003nobodyさん
2007/08/03(金) 08:22:36ID:???0004nobodyさん
2007/08/04(土) 17:47:54ID:???$ethna_dir= '/usr/local/bin/lib/Ethna'; //Ethna本体が入っているディレクトリを指定する
$pattern = $ethna_dir.'/*';
$files=glob($pattern);
while(count($files) > 0){
foreach($files as $file) {
conv_file($file);
}
$pattern.='/*';
$files=glob($pattern);
}
function conv_file($file) {
global $ethna_dir;
if(is_dir($file)) return;
$body = file_get_contents($file);
if(stripos($body, 'EUC-JP')){
if($file!=$ethna_dir.'/class/Ethna_SmartyPlugin.php'){
$body=str_ireplace('EUC-JP', 'UTF8', $body);
}
}
$body = mb_convert_encoding($body, 'UTF8', 'EUC-JP');
file_put_contents($file, $body);
}
0005nobodyさん
2007/08/04(土) 17:54:15ID:???http://d.hatena.ne.jp/riaf/20070701/1183286248
0006nobodyさん
2007/08/19(日) 22:21:51ID:???/  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ /
/ Web1.0時代を担った /
/ このフレームワークは無事に /
/ 開発を終了致しました /
/ ありがとうございました /
/ /
/ モナーより /
/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄/
∧_∧ / /∧_∧
( ´∀`) / /(´∀` )
( つ ⊂ )
| | | | | |
(__)_) (_(__)
0007nobodyさん
2007/08/20(月) 02:13:10ID:hkP4IXYg0008nobodyさん
2007/08/26(日) 21:14:01ID:3CqBNeOxethna上でsmartyのdebugging consoleをONにしたい場合は
どうすればいいのでしょうか?
テンプレートに渡されている値が知りたいのです。
しょうがないので今はtemplate内で{debug}と書いて
確認してます。
0009nobodyさん
2007/08/26(日) 22:28:04ID:???APPID_ViewClassあたりに加えておけば?
0010nobodyさん
2007/08/27(月) 17:44:17ID:JOZKKR6F$renderer->engine->debugging = true;
としたら動きました!
ありがとうございます。
0011nobodyさん
2007/08/29(水) 18:09:54ID:d9IxmgRc環境:Redhat + Apache + Ethna2.3.2 + PHP5.2.3 + PostgreSQL7.4.17
この環境でWEB+DBの状態です。
EthnaからDBに接続する際に以下のエラーが出ます。
(ERR): Ethna_DB_PEAR.connect(class/Ethna_Backend.php:411): DB接続エラー: [DB Error: connect failed] ** pgsql(pgsql)://dbuser:PASSWORD@tcp+localhost/testdb?new_link=1 [ERROR CODE(2)]
dsnの設定は
'dsn' => 'pgsql://dbuser:password@localhost/testdb',
となっております。pg_hba.confの設定確認の為に、
該当マシンにtelnetで接続し、postgresユーザーにて
psql -u testdb の問いでuser:dbuser pass:password
とすると接続する事が出来ます。
考えられうる原因はどのような物でしょうか?
0013nobodyさん
2007/08/29(水) 21:58:30ID:???11です。
Apache(PHP,Ethna)から見て、同一マシンにインストールした
DBに接続する為、localhostで問題ないのかと思っておりました。
この認識は間違っているのでしょうか?
確認の為、サーバのIPアドレスを指定してみましたが、結果は同じエラーでした。
的外れな事を言っていたら申し訳有りません…。
0014nobodyさん
2007/08/30(木) 00:48:46ID:???0016nobodyさん
2007/08/30(木) 11:41:22ID:???11です。ありがとうございます。
15様の仰る通り、pg_connectしてみた所、以下のエラーが発生しましたが
Warning: pg_connect() [function.pg-connect]: Unable to connect to PostgreSQL server: could not connect to server: Connection refused Is the server running on host "localhost" and accepting TCP/IP connections on port 5432?
お陰様で、エラーメッセージがより直接的になった為、これを調べたところ
pg_connect("dbname=testdb user=dbuser password=password")
の形で(host指定外し)行ける事が判明しました。全くEthna関係なかったです。大変申し訳有りませんでした…。
もう少し詳細に調べ、pgsql/data/postgresql.confのtcpip_socket = trueを変更する事で
host指定も可能なようですが、localhostから以外は接続しないため、これは設定しない形で終えました。
解決の糸口を下さった方々に感謝致します。本当にありがとうございました。
0018nobodyさん
2007/08/30(木) 16:02:13ID:???つなぎに行くからな。
Ethna関係なしsage
0019nobodyさん
2007/09/09(日) 00:35:07ID:R9DBCM/b最近更新が少ないよね。
まあGREEで使用されているからGREEが潰れないうちは
開発続けていくんだろうけど。
0020nobodyさん
2007/09/09(日) 00:58:35ID:???レン鯖にPEARが入ってない場合、どうすればいいの?
0022nobodyさん
2007/09/09(日) 01:19:37ID:???0023nobodyさん
2007/09/09(日) 10:56:51ID:???0024nobodyさん
2007/09/09(日) 11:40:17ID:???これはw
Ethnaで運用してたらEthnaの穴と思われたけど
Pukiwikiで運用してるからセキュリティホールのそしりは免れたね
0025nobodyさん
2007/09/09(日) 11:45:09ID:???ロボットに釣られんなよ。
0026nobodyさん
2007/09/12(水) 07:43:28ID:???ORM初めて何でなかなかコツが掴めない
0027nobodyさん
2007/09/12(水) 10:00:03ID:???itohさんとかriafさんとかのブログでいくつか記事があるかな。
0028nobodyさん
2007/09/12(水) 23:01:07ID:???そのブログ当たってみます
ありがとう
0029nobodyさん
2007/09/13(木) 02:43:53ID:k28u4udrコードも相当きれいだし、読みやすい。
SymfonyとかcakePHPとか、確かになんでもできるんだろうけど、
フレームワーク病に掛かりやすい。RoRのレールを外れた時の
ものすごい無力感に似た感じで。
あと、軽いね。F.W自体のベンチって難しいけど。
だから、Ethnaをベースにオレ的汎用コードを少しずつ加えていって
割と資産を作りやすい。あくまでオレ的汎用なんだけど。
まぁ、自分の本業がいわゆるホームページ制作だからだけど、
2年Ethna使って「これできない!」ってことなかったし、
使い続けて良かったと思うことは多いな。
0031nobodyさん
2007/09/13(木) 07:49:48ID:???例えば、
user {
id primary
name
gid
}
group {
id primary
name
}
user_group_link {
uid
gid
}
って3つのテーブルがあるとしてMySQL、MyISAMなDBな場合に
ユーザ一覧→ユーザ個別修正
グループ一覧→グループ個別修正
の4つの画面を作るとしてその中でどんな感じでAppObject/AppManagerを使えばいいのかを
ざっくり書いて貰えると嬉しいにょー
一覧にuser.nameでのlike検索とか付ける場合どんな感じでAppManagerを
使えばいいかとか、joinするときはAppObjectを合成してほげほげとかもあると最高
0032nobodyさん
2007/09/13(木) 18:53:31ID:???0033nobodyさん
2007/09/14(金) 03:30:34ID:???join編期待してあす。
テーブルの項目名に日本語を使いたいので
ちょっとアレして↓な感じで遊んでみます。
// Ethna_AppObjectをSmartyに渡すとMemory使いすぎで怒られる
// ので怒られないようにヘルパーを入れてみる
// AppObject::getMinimal() とか作ってそこで生成した方が
// よいかも知れない
class APPID_MinimalAppObject {
var $prop;
function APPID_MinimalAppObject(&$obj) {
// AppObjectからハッシュをゲッツ
$this->prop =& $obj->prop;
}
function get($key) {
return $this->prop[$key];
}
}
if($diary->isValid()){
//あったとき
- $this->af->setApp('diary', $diary->getNameObject());// テンプレートで{$app.diary.body}とかで取得できるようになる
+ $smarty =& $this->backend->ctl->getRenderer();
+ $helper =& new APPID_MinimalAppObject(&$diary);
+ $smarty->assign_by_ref('diary', &$helper);
} else {
//無いとき
}
お目汚し失礼しました。
003430
2007/09/14(金) 03:44:54ID:???> ユーザ一覧→ユーザ個別修正
典型的なパタンだね。
俺の場合一覧と個別は、
action/Admin/User.php
action/Admin/User/Edit.php
action/Admin/User/Edit/Conf.php
action/Admin/User/Edit/Do.php
view/Admin/User.php
view/Admin/User/Edit.php
view/Admin/User/Edit/Conf.php
って作る。
actionとしては上から、
・ユーザー一覧
・ユーザー登録(編集)
・ユーザー登録編集確認
・ユーザー登録実処理
で、
view/Admin/User.php
でユーザー一覧表示させるためのリストを作るけど、一覧データを持ってくるのは
User.phpでは基本的には1行(PHP4なら2行)
preforwardで
$this->af->setApp('user', $this->backend->getManager('User')->getUserList());
って書く。
PHP4だと、これできないから
$user_m =& $this->backend->getManager('User');
$this->af->setApp('user', $user_m->getUserList());
003530
2007/09/14(金) 03:45:29ID:???AppManagerは、デフォルトで使うもんとすると
PROJECTID_UserManager.php に
PROJECTID_UserManager extends Ethna_AppManager
ってできてる。これをインスタンス化してよんでるのが
$this->backend->getManager('User')
だから、PROJECTID_UserManager.php に
PROJECTID_UserManager::getUserList()
を作成する。
で、これの中身で一番シンプルなのは
function getUserList()
{
return $this->getObjectPropList('User');
}
帰ってくるのは配列で、1つ目の要素は検索した全ユーザーのリスト。2つ目の要素は、ユーザー情報を配列で。
まぁ、素直にvar_dumpすればわかる。
003630
2007/09/14(金) 03:46:35ID:???実際はこれだけだと意味がないんで、
function getUserList($name)
{
}
とかして、$nameに部分一致なUserのリストを返すようにする。このとき使うのはEthna_AppSearchObject
具体的には
function getUserList($name)
{
$filter = array('name' => new Ethna_AppSearchObject($name, OBJECT_CONDITION_LIKE));
return $this->getObjectPropList('User', null, $filter);
}
ってする。
IDの逆順にしたい!というときもあるかと思う
ORDER BY ID DESC, NAME ASC とかしたい場合もあると思う。その場合は
function getUserList($name)
{
$filter = array('name' => new Ethna_AppSearchObject($name, OBJECT_CONDITION_LIKE));
$order = array('id' => OBJECT_SORT_DESC, 'name' => OBJECT_SORT_ASC);
return $this->getObjectPropList('User', null, $filter, $order);
}
ってやる。
003730
2007/09/14(金) 03:47:13ID:???LIMIT 10,20
ってやりたい場合は、
function getUserList($name, $offset, $limit)
{
$filter = array('name' => new Ethna_AppSearchObject($name, OBJECT_CONDITION_LIKE));
$order = array('id' => OBJECT_SORT_DESC, 'name' => OBJECT_SORT_ASC);
return $this->getObjectPropList('User', null, $filter, $order, $offset, $limit);
}
って感じ。
とりあえず、Ethna_AppManager::getObjectPropListを覚えておけば9割くらい
AppManager使えることになる。
本当は、getObjectPropListの返り値がEthna::isError()でエラー起こしてないか
チェックするんだけど。
003830
2007/09/14(金) 03:48:27ID:???action/Admin/User/Edit/Do.php
だけだな。
AppObjectは、MySQLのテーブルデータの1ラインそのものだと思ってもらってかまわない。
それがORM。
なので、新しくユーザーを追加したい場合は、データが空のAppObjectを一つ作る
PROJECTID_Action_AdminUserEditDo::perform();で
function perform()
{
$user =& $this->backend->getObject('User');
}
ってやる。これだけだとまだ追加してないので何も起こらない。
そこで$userに、データを詰め込む。これはActionFormとの連携で
function perform()
{
$user =& $this->backend->getObject('User');
$user->importForm(OBJECT_IMPORT_IGNORE_NULL);
}
これで、適切に設定してればフォーム値がそのままAppObjectに入る。
003930
2007/09/14(金) 03:49:19ID:???まだDBには追加されてない。最後に
function perform()
{
$user =& $this->backend->getObject('User');
$user->importForm(OBJECT_IMPORT_IGNORE_NULL);
$user->add();
}
で終わり。
新しくユーザーを作るんじゃなくて、既存ユーザーの編集なら
function perform()
{
$user =& $this->backend->getObject('User', 'id', $id);
$user->importForm(OBJECT_IMPORT_IGNORE_NULL);
$user->update();
}
で終わり。最初の行で、id=$idのユーザーデータを持ったAppObjectが取れる。
ただ、この場合は、確実にid=$idのレコードが存在して、取れているかを
確認するために
function perform()
{
$user =& $this->backend->getObject('User', 'id', $id);
if ($user->isValid()){
$user->importForm(OBJECT_IMPORT_IGNORE_NULL);
$user->update();
}
}
ってやって、有効性を確認する。
004030
2007/09/14(金) 03:50:25ID:???Ethna_AppManager::getObjectListを使う。getObjectPropListは配列を返したけど、
getObjectListは第二引数がAppObjectを要素に持った配列になってる。当然getObjectPropListより重いよ。
004130
2007/09/14(金) 03:52:06ID:???>getObjectListは第二引数がAppObjectを
getObjectListは返り値の2つ目の配列がAppObjectを
004226,33
2007/09/14(金) 07:57:02ID:???週末試しまくります。
ありがとうありがとう。
004326,33
2007/09/15(土) 07:04:30ID:???俺的まとめ
WebProgを極めて居酒屋を開発する - AppObjectの使い方
http://d.hatena.ne.jp/riaf/20070913/1189675267
WebProgを極めて居酒屋を開発する - AppObjectでJOINする方法
http://d.hatena.ne.jp/riaf/20070914/1189747693
AppManagerの使い方
http://pc11.2ch.net/test/read.cgi/php/1186096518/34-41
0044nobodyさん
2007/09/21(金) 02:13:40ID:???0045nobodyさん
2007/09/25(火) 15:30:02ID:???0046nobodyさん
2007/09/25(火) 18:45:28ID:???とか?
0047nobodyさん
2007/09/25(火) 19:42:56ID:???そもそもが分かりやすくないので俺にはミリでした。
が、
http://ethna.jp/ethna-document-dev_guide-urlhandler.html
に加えて、はまりどころ
・www/index.phpに$_SERVER['URL_HANDLER']を忘れない
・AppID_UrlHandler.phpに_getPath_Hogeを忘れない。
・pathが被る場合は順番に気をつける
例:
var $action_map = array(
'hoge' => array(
'archive' => array(
'path' => 'archive',
...(snip)...
),
'archive_recent' => array(
'path' => 'archive/recent',
...(snip)...
),
とすると、'path' => 'archive'が先にマッチして'path' => 'archive/recent'まで見てくれない。
$action_mapはforeachでループしてるだけなので順番がまずいとまともに動かない。
pathとpath_regexpは、複雑なマッチを配列上で優先させること。
・path_extが要らない場合でも'path_regexp'と配列の個数を合わせる。
'path_regexp' => array('|^hoge$|', '|^hogehoge$|'),なら、
'path_ext' => array(array(), array()),としておかないと動かない(っぽい)。
アクションをサイト直下(http://example.com/とか)にマップする場合は'path_ext'=>array(),で。
0048nobodyさん
2007/09/25(火) 19:49:41ID:???setcookie($this->session_name, "", 0, "/");
の行全部を
list(, $path, $domain,) = session_get_cookie_params();
setcookie($this->session_name, '', 0, $path, $domain);
に変えておくと
session_set_cookie_params(1200, '/admin/', '', true, true);
とかエントリポイントで指定できて便利とか。
0049nobodyさん
2007/09/27(木) 17:12:13ID:???アクションフォームの定義の仕方がわかりません
$_POST等を直接弄るしか無いんでしょうか・・・
■ このスレッドは過去ログ倉庫に格納されています