1read 100read
2012年07月WebProg242: 【PHP】Ethna part.2【国産フレームワーク】 (306) TOP カテ一覧 スレ一覧 2ch元 削除依頼
PDFのWebページは糞 (702)
【MT】MovableType【設置方法】 (889)
【PHP】ツリー掲示板を作ろう (380)
Perlのオブジェクト指向って無理やり実装だなw (266)
自作CGIを評価するスレ (667)
ファイルメーカーでどこまでできるウェブアプリ! (461)

【PHP】Ethna part.2【国産フレームワーク】


1 :2007/08/03 〜 最終レス :2012/04/17
国産フレームワーク、Ethnaでいい意味で手抜きなプログラミングライフを。
Ethna -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/

2 :
Q. 公式のドキュメント以外にわかりやすい説明無いの?
A. 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/

3 :
CSRFtってなに?

4 :
既存EthnaをUTF8にする方法(その2)
$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);
}

5 :
DBの文字コード云々
http://d.hatena.ne.jp/riaf/20070701/1183286248

6 :
             o
             /  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ /
            / Web1.0時代を担った   /
           / このフレームワークは無事に /
           / 開発を終了致しました  /
          / ありがとうございました  /
          /                /
         /    モナーより      /
         / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄/
  ∧_∧  /                /∧_∧
 ( ´∀`) /                /(´∀` )
 (     つ               ⊂     )
 | | |                   | | |
 (__)_)                  (_(__)

7 :
Ethna3マダー?

8 :
こんにちは。最近になってethnaを使い始めた者です。
ethna上でsmartyのdebugging consoleをONにしたい場合は
どうすればいいのでしょうか?
テンプレートに渡されている値が知りたいのです。
しょうがないので今はtemplate内で{debug}と書いて
確認してます。

9 :
Ethna_Renderer_Smartyを書き換えるか
APPID_ViewClassあたりに加えておけば?

10 :
APPID_ViewClassにおいて
$renderer->engine->debugging = true;
としたら動きました!
ありがとうございます。

11 :
質問させて下さい。
環境: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
とすると接続する事が出来ます。
考えられうる原因はどのような物でしょうか?

12 :
>>11
接続先はlocalhostでいいの?

13 :
>>12
11です。
Apache(PHP,Ethna)から見て、同一マシンにインストールした
DBに接続する為、localhostで問題ないのかと思っておりました。
この認識は間違っているのでしょうか?
確認の為、サーバのIPアドレスを指定してみましたが、結果は同じエラーでした。
的外れな事を言っていたら申し訳有りません…。

14 :
confiureとか、phpinfoの情報さらしてみれば?(可能な限り)

15 :
>>13
つーーか。Ethnaどうこう言う以前に、普通にpg_connectしてselectできるのかと。

16 :
>>14,15
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から以外は接続しないため、これは設定しない形で終えました。
解決の糸口を下さった方々に感謝致します。本当にありがとうございました。

17 :
>>16
あっ。俺もその問題なったよw
違うフレームワークだけどさ。
同じようにlocalhostはずしたら動いた。

18 :
localhostだとUnix Socket経由で接続しにいくけど、127.0.0.1だとTCP/IPで
つなぎに行くからな。
Ethna関係なしsage

19 :
しかしethnaは開発続けていく気があるのだろうか。
最近更新が少ないよね。
まあGREEで使用されているからGREEが潰れないうちは
開発続けていくんだろうけど。

20 :
何も予備知識無くて質問するけど、ethnaってPEARがいるそうだけど、
レン鯖にPEARが入ってない場合、どうすればいいの?

21 :
>>20
libにPEARコピーしておいておく。

22 :
PEARがなくても動くCakePHPにしたよ。

23 :
HACKED BY ALEMIN KRALI?なんかされたのかな http://ethna.jp/

24 :
>>23
これはw
Ethnaで運用してたらEthnaの穴と思われたけど
Pukiwikiで運用してるからセキュリティホールのそしりは免れたね

25 :
単に凍結してなかったから編集されただけだろ。
ロボットに釣られんなよ。

26 :
AppObject周りをがっつりレビューしてるサイトないかなぁ
ORM初めて何でなかなかコツが掴めない

27 :
AppObjectはコミッターの人たち使ってないらしいからな・・
itohさんとかriafさんとかのブログでいくつか記事があるかな。

28 :
そうなのか。
そのブログ当たってみます
ありがとう

29 :
Ethnaの長所って、「コードが全部読める範囲」って言うとこだと思う。
コードも相当きれいだし、読みやすい。

SymfonyとかcakePHPとか、確かになんでもできるんだろうけど、
フレームワーク病に掛かりやすい。RoRのレールを外れた時の
ものすごい無力感に似た感じで。
あと、軽いね。F.W自体のベンチって難しいけど。

だから、Ethnaをベースにオレ的汎用コードを少しずつ加えていって
割と資産を作りやすい。あくまでオレ的汎用なんだけど。

まぁ、自分の本業がいわゆるホームページ制作だからだけど、
2年Ethna使って「これできない!」ってことなかったし、
使い続けて良かったと思うことは多いな。

30 :
>>28
自分も相当AppObject/AppManagerは使ってるから分からなかったら
ここで答えるよ。

31 :
何々がわからないって質問できるほど理解してないだなこれが
例えば、
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を合成してほげほげとかもあると最高

32 :
riafさん優しすぎるwwwww

33 :
riafさん、ありがとう。
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 {
   //無いとき
  }
お目汚し失礼しました。

34 :
>って3つのテーブルがあるとしてMySQL、MyISAMなDBな場合に
> ユーザ一覧→ユーザ個別修正
典型的なパタンだね。
俺の場合一覧と個別は、
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());

35 :
このとき使ってるのがAppManager
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すればわかる。

36 :

実際はこれだけだと意味がないんで、
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);
}
ってやる。

37 :
さらに、
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()でエラー起こしてないか
チェックするんだけど。

38 :
AppObject使うのは、
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に入る。

39 :

まだ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();
}
}
ってやって、有効性を確認する。


40 :
で、AppManagerからAppObjectを一括取得して、一括Updateとか掛けたい場合は、
Ethna_AppManager::getObjectListを使う。getObjectPropListは配列を返したけど、
getObjectListは第二引数がAppObjectを要素に持った配列になってる。当然getObjectPropListより重いよ。

41 :
間違えた
>getObjectListは第二引数がAppObjectを
getObjectListは返り値の2つ目の配列がAppObjectを

42 :
おお、ありがとうございます。
週末試しまくります。
ありがとうありがとう。

43 :
30さん、raifさん、ありなとうありがとう。
俺的まとめ
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

44 :
誰かurlhandlerを解りやすく説明して・・・・

45 :
セッションオブジェクトからセッションIDって取得出来るんでしょうか?

46 :
$session->session_name
とか?

47 :
>>44
そもそもが分かりやすくないので俺にはミリでした。
が、
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(),で。

48 :
Ethna_Sessionは
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);
とかエントリポイントで指定できて便利とか。

49 :
ある入力画面で、マスタの数によってINPUTの数が変わる画面があるんですが、
アクションフォームの定義の仕方がわかりません
$_POST等を直接弄るしか無いんでしょうか・・・

50 :
>>49
この頁の解説なんかどうでっしゃろう?
http://ethna.jp/ethna-document-dev_guide-form-type.html
-- html
<input name="foo[]" value="v1" ...
<input name="foo[]" value="v2" ...
<input name="foo[]" value="v3" ...
-- /html
-- ActionForm
'foo' => array(
'type' => array(VAR_TYPE_STRING),
),
-- /ActionForm

51 :
うほ、ありがとうございます!
アクセスさえ出来ればあとはどうにでもなりますね
もしくはマスタ数に上限を設けて、requiredがfalseなフォーム値を
上限分書いて逃げようと思います

52 :
Ethnaにアバター機能が付くと聞いて飛んできましたw

53 :
>>47
d
規制で書けんかった(´・ω・`)
php5ならいちいさんが書いてる
Net_URL_Mapperを使ったプラグインがよさげなんだがなぁ・・・
ところで、UrlHandlerで設定した値ってもうちょっと簡単に取得できないもんなんだろうか・・・
AFに定義しないと取得できないってめんどい・・・・

54 :
基本的にindex.phpのみでテンプレートを切り替えて
アクションをPOSTして動かしていくイメージで作っていたのですが
当然ですが、アクセスログを見ても全てindex.phpになっているため
画面毎に固有のURLを割り振りたいと考えています。
イメージとしては、 入力画面 -> 確認画面 -> 完了画面
のそれぞれに固有のURLを割り振る方法を模索しています。
入力画面:index.php?code=input
確認画面:index.php?code=confirm
完了画面:index.php?code=finish
と言うレベルでも付与出来るならば問題無いのですが、アクションをPOSTしながら
URLに変化を付ける方法が分かりませんでした。
素直にGETで渡すしかないのでしょうか?

55 :
>>54です。
書いた直後に気が付いた…。
これなら普通に<form action="index.php?=***">で渡せば良いやと言う事で…
スレ汚し、大変失礼致しました。

56 :
>>54
<input type="hidden" name="action_*">
とか
<input type="submit" name"action_*" value="じっこ〜">
とかname属性に入れれば良い
ここらへんはEthnaのチュートリアルにあるよ

57 :
smartyのincludej関数を使って、ヘッダー部やフッター部を別ファイルにしたいのですが
それ様の格納フォルダみたいなものってないのでしょうか?もしくは何か良い方法あれば
お願いします

58 :
>>57
テンプレートディレクトリの中に好きなようにディレクトリ作って突っ込めばいいですよ。

59 :
ログの出力をなんでもいいから全部ファイルに出力したいときはどうするのん?

60 :
'log_facility'          => 'file',
'log_level'             => 'debug',

61 :
おお、ありがたい
ちなみになんだけど
Ethna_Controller の getManagerClassName と getObjectClassName 。
微妙に名前の変換ロジックが違う
CVS版だと同じになってんのかな?

62 :
http://ihc.mydisk.jp/

63 :
EthnaのADODBって Starttrans() 使えないのかな?トランザクション。

64 :
直接
$this->db->db->StartTrans();
って呼べば使えたと思う

65 :
>>63-64
いやいや、PEAR_DB版でもADOdb版でも、トランザクションは
$this->db->begin();
$this->db->rollback();
$this->db->commit();
で統一されてるよ。

66 :
Ethna_DB_ADOdb.phpだとbegin()で単にBeginTrans()を呼んでるだけだけど、ADOdbのStartTrans()ってBeginTrans()より色々とよきに計らってくれるんですよ
/**
 Improved method of initiating a transaction. Used together with CompleteTrans().
 Advantages include:
             
 a. StartTrans/CompleteTrans is nestable, unlike BeginTrans/CommitTrans/RollbackTrans. Only the outermost block is treated as a transaction.
 b. CompleteTrans auto-detects SQL errors, and will rollback on errors, commit otherwise.
 c. All BeginTrans/CommitTrans/RollbackTrans inside a StartTrans/CompleteTrans block are disabled, making it backward compatible.
 */
function StartTrans($errfn = 'ADODB_TransMonitor')
{....

67 :
ぐあ、StartTrans()のことは知らなかった。ごめん、typoかと…orz
CompleteTrans()でエラーを自動判定したり、トランザクション中に
別のメソッドでcommitされても大丈夫というのは便利ですね。
ADOdbの独自拡張ぽいから、Ethna_DB_ADOdb.phpを拡張するか、>>64氏の
書いたように直接呼ぶのが良さそう。
# ドキュメントに「毎回エラーチェックする必要ないよ」て書いてあるのは
# 無駄にSQLの実行回数が増えてしまうので微妙な気もするけど…

68 :
詳しい人おしえて、
Ethna使ってて actionに書くべきか viewに書くべきか迷うんだが、
例えばactionで
AppManager使って必要なデータ取ってきてたとして
ついでに af->set()で出力のお膳立てもしてしまった方が楽に感じるんだが、
あえて、どこかに溜めておいてview側でaf->set()すべきなのかね?

69 :
>>68
actionformのsetはactionclassのperformに入る前の段階
つまり、authenticateとprepareで行うべき。
viewでやるのはもってのほか。
AppObject/AppManagerなどのModelにも極力行かすべきではない。

というルール付けでやってMVC意識してる。

70 :
>69 Ethna使わないでください。

71 :
>>70
どういうこと?

72 :
>>68
その辺はMVCのジレンマだと思う。
効率的には、Actionで取得した情報をViewで使えるのがいいけど
特定のActionを通過しないとView側で正しい情報を利用できない
となると、処理と表示が分離されないことになるから微妙。
自分は多少無駄だとは思いつつも、ActionとViewでそれぞれ取得
しているよ。結果をキャッシュできるものはキャッシュしたり、memcachedを
使ったりして、DBの負荷は上げないように少し考えてはいるけど。

73 :
>>72
それ af->setApp() するときだよね?
>>68 は、af->set()って書いてるから、フォームの値を調整したいんだろ?
そう思って>>69 の書き込みなんだが。
> 自分は多少無駄だとは思いつつも
AppObjectはキャッシュ持ってるから一回取りに行った値は保存してる。
なんでAppObject使ってやればActionで判定にとった値をViewで
使いまわしてもDBには行かない。
その辺はORMの仕事じゃないかとも思うけど。

74 :
なかなか興味深い

75 :
ごめん af->setApp()のこと。。。orz >69
MVCの切り口でいくと
やはりそうなるんですかね。>72 >73
キャッシュされているにせよ
viewでもう一回AppObject取り直して
af->setApp()を数行書くってのも、たいそう無駄な気がしてます。
結局どんなAppObjectが渡って来るか
view自体知ってなくてはならない訳だし、
俺の場合描画上の小細工はSmartyのテンプレートにやらせる事が
多いんで、
それだったら、set()とかsetApp()ひっくるめて、
ActionForm全体を渡すから、viewさんあとは描画よろしく。
って方が潔い気がしてます。
Ethnaは viewの定義省略できるんだし、
ワザワザ2,3行だけのViewのファイル作らなくても良いかなと
思ってる。
こういうのMVC的にはダメなのかな。

76 :
>>75
とりあえず1分でも早いことコーティング終わらせたい!
って時は、確かにViewレスにしてperformでsetAppする。こともある。
前はそうやってたけど、最近面倒でもviewつくるようにしてる。
まぁ、1分かからんでしょ。
理由は2つあって、ひとつは、結局あとから追加仕様が加わった時に
viewがあるとそこに流し込めば良いという意識でAction作ってしまえる。
viewを造ってないと、結局違うActionに同じsetAppするようになる。
ある意味、そっちの方が絶対使い回しできない。
もうひとつは、forwardをいじりたい場合。
view/Subview.php
view/Subview/Draw.php
view/Subview/Draw/Finish.php
ってする場合、APPID_View_Subview::forward()に仕掛けをしてやって
テンプレパス変えたりする場合、クラス定義だけでもしておけばそれ以下の
viewもよろしくやってくれるけど、viewを定義しないとControllerで設定した
view使っちゃうからな。まぁ、特殊な場合だけど、forwardいじれるのは強力だからな。

77 :
>>75
>キャッシュされているにせよ
>viewでもう一回AppObject取り直して
>af->setApp()を数行書くってのも、たいそう無駄な気がしてます。
なんで、オレの場合はできる限りAction/Viewの行数を増やさないように
Modelにほとんどのコードが移動した。
AppObject/AppManagerのキャッシュを利かせるには、
同じfilter/offset/limit/orderでDBからfetchさせる必要があるから。
すると、ActionとViewでぶれがあるといけないからな。
だから、全体の流れとして必然的に
[Action]
ActionFormの調整(デフォルト値や、セレクトタブの値生成)
  ↓
af->validate()
  ↓
落ちるView先の決定ロジック
[View]
af->setApp()
のみ
ってなる。

78 :
>>76
>もうひとつは、forwardをいじりたい場合。
これは分る。確かにforwardいじりたい時もある。
>viewを造ってないと、結局違うActionに同じsetAppするようになる。
>ある意味、そっちの方が絶対使い回しできない。
そうかなー。viewを作ってあったにせよ、viewに渡すものが抽象化
しきれてなければ、結局使い回せない気がする。
一番抽象的で、どんなviewでも理解できるもの、つまりはActionFormを
渡すというお約束が、ゆるくて最強の接点だと思うんだが。

79 :
>>77
>AppObject/AppManagerのキャッシュを利かせるには、
>同じfilter/offset/limit/orderでDBからfetchさせる必要があるから。
勉強になります。

80 :
>>78
>渡すというお約束が、ゆるくて最強の接点だと思うんだが。
その辺は、開発スタイルとか案件に依るんじゃない?
取りあえず「オレはこういう感じでやってる」ってだけで、別に色々な方法があると思う。
使ってるうちに変わるだろうし、ってオレがそうなんだけど。
そのへんのゆるさはEthnaのいいところだし、一人や数人でやる分には気楽。

81 :
みんな、AppObjectというかORM使ってるのか。
俺はjoinのやり方が分からなくて涙目だったので、いまだにSQL書いてるよ。
ZnedFrameworkも試してみたけど、Zend_Db_Tableが全然使えないので
結局そっちもSQLというJスっぷりだぜ。

82 :
joinは少し前まで、まともにできなかったはず。
なんで漏れもSQL書いてるよ。AppObjectはテーブルのレコードと1対1でやり取りする場面だけ
使ってる。検索して一覧引っ張ってくるようなケースは、joinする場合が多いし、
where文SQLで書く方が慣れているんで、SQL書いた処理をAppManagerに詰め込んでるよ。

83 :
view作ってwhere条件だけEthna_AppSearchObjectで作るってのはナシ?
もっとも、それやった香具師がMLで「table読むときはカラム名小文字になるのに、viweを読むと大文字になる。がっでむ!」と言っていたので、あまりお勧めではないのかもしれん。
……S2EthnaでS2Dao.PHPか?w

84 :
http://ethna.jp/ethna-document-dev_guide-app-sjis.html
> 入力のShift_JISを内部コードに変換
> まずは、Ethnaのフィルタで入力コードを変換してしまいます。
とあるのですが
/usr/local/lib/php/Ethna/class/Ethna_Filter.php
この中に書き加える訳ではないのですか?
上記で駄目だったので、APPID_Filter.php を以下のように書いて
class APPID_Filter extends Ethna_Filter{
{
  function prefilter(){・・・}
  function InputEncoding($data){・・・}
}
APPID_Controller.phpでrequire onceしてみたりしたのですが
$_POSTされたデータが変換されなくて悩んでます。
どなたかご教授ください。よろしくお願いします。

85 :
APPID_Filter.php の prefilter() は preFilter() の入力ミスです。

86 :
だれかAppManagerのgetAttrListの使い方わかる人いませんか?
これがいまいちわからないのです。フォームヘルパでセレクトボックスのoptionの値を
データベースから取得したいと考えてまして。
Ethnaの開発マニュアルみていたら、アクションフォームで
Optionの設定を'address,prefecture'に書けば見たいな事わかったんですが、、
プロパティの値ってのがよくわからないんです・・・

だれかわかる人教えてください。


87 :
Hogeマネージャの関数から
同マネージャ内の別関数(fuga)を呼び出したい場合、
以下のどちらが適しているでしょうか?
$Hoge_m =& $this->backend->getManager('Hoge');
$Hoge_m->fuga();
or
$this->fuga();


88 :
>87
$this->fuga();


89 :
ありがとうございます!!
もう一点非常に疑問点があるのですが、
$Hoge_m =& $this->backend->getManager('Hoge');

$Hoge_m = $this->backend->getManager('Hoge');
ってどう違うのでしょうか?
この&って参照渡しでしょうか?
参照渡しって単なる変数だけでなく、オブジェクトに対しても
利用可能なのでしょうか?


90 :
>>89
http://www.php.net/manual/ja/language.references.php
参照はスカラー型でもオブジェクトや配列でも使えるよ。
余談だけど、PHP5以降では関数の戻り値や変数への代入なんかで
同じオブジェクトを指し示している必要がないのであれば、参照渡しを
するべきではないので注意。メモリの効率化とか思っていると、むしろ
無駄に消費されることがある。
http://www.phppro.jp/news/304
PHP4/5に対応するEthna(本体)には関係ない話だけどね。

91 :
このフレームワークって他のフレームワークにあるような
AjaxヘルパやHTMLヘルパーなんかは装備されないんでしょうか?
あと、ルーティングをもう少し改善して欲しいですな。

92 :
スマートURLを使えるようにするにはapacheの方も色々設定しないと駄目?

93 :
PEAR::Authを継承したAuthクラスをこさえてみようかと思ったんだが、
構築するタイミングがわからない
ActionForm辺りで
$this->auth =& new $this->backend->ctl->class['auth'](&$this->backend->ctl)
ってやってあげればいいんだべか。
Controllerのコンストラクタで構築するのはちょっくら早い感じだし
どうするとスマートなんでげしょ。

94 :
>>92
まぁ、mod_rewriteの設定を行わないと駄目でしょうね。
UrlHandlerはいまひとつって感じ。

95 :
ActionClassのauthenticateで生成することにすますた

96 :
例外処理をしたいのですが、
AppManager 内で
throwして
アクション内でcatchしたい場合、
どのように記述すればよいでしょうか?
単にAppManager内でthrowすると
PHP Fatal error: Uncaught exception 'Exception'
がおきてしまいます

97 :
>>67
エラーが発生したらトランザクション中の後続するSQLはスキップしそうだけどね
そうじゃなきゃあんまりでしょw

98 :
>>97
いや、ソース確認したらチェックしてなかったんだよ
あんまりだ

99 :
$obj =& $this->backend->getManager('hoge');
$obj->setParam( $param );
$obj =& $this->backend->getManager('hoge');
みたいな感じにすると
$obj->setParam( $param );が既になされている状態になる理由が
よくわからんです。


100read 1read
1read 100read
TOP カテ一覧 スレ一覧 2ch元 削除依頼
PHP初心者勉強会やらんかね! (477)
MySQL vs PostgreSQL (379)
XML (336)
【Perl上級者コーナーPart01】 (626)
Perl VS PHP (542)
【SWFで】Macromedia Flex【RIA】 (808)
--log9.info------------------
Amazon vs 楽天 勝者になるのはどっち? (228)
【docomo】SH-07c【SHARP】 (974)
電子書籍のフォーマット (298)
【東芝】BookPlace DB50■01冊目【リーダー】 (280)
【Xperia】Android端末で読書【Desire】 (528)
【ChainLP】自炊データ変換ソフト【PDFDiet】3冊目 (542)
【自主】電子書籍作成スレ【作成】 (383)
自炊の森について (369)
au biblio Leaf SP02 part2 (789)
絵本作家になりたい 第十一刷 (220)
うろ覚えの絵本の作者やタイトル教えて!・13冊目 (495)
おやつが食べたいな〜 6 (641)
リサとガスパール6 (206)
テスト用だから自由に使ってね (570)
おやつが食べたいな〜 6冊目 (644)
あの本のタイトル教えて!@児童書板 15冊目 (497)
--log55.com------------------
【NBA】八村塁 Part.76【Washington Wizards】
◆◆◆ B.LEAGUE(Bリーグ)162 ◆◆◆
☆☆NBA 2019-20 シーズン(中断)スレ part135☆★
【全力応援】長岡望悠10【完全復帰祈願】
【引退・移籍】選手進路総合スレ25【内定・復帰】
全日本女子1155
【超戦w】ヴォレアス北海道4【来るなV1】
栗田工業ウォーターガッシュ