ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

Let's PHPコミュのMVCで、オブジェクトを使用して値を受け渡す方法

  • mixiチェック
  • このエントリーをはてなブックマークに追加
今、MVCでシステムを組もうとしているのですが、オブジェクトを使用して値を受け渡すところで、行き詰っています。市販の書籍では、あまりPHP4でオブジェクト指向開発を取り上げた本がないようで、なかなか分かりません。PHPマニュアルの「リファレンス」のあたりも目を見ましたが、どうすればよいのかよく分かりませんでした。もし分かる方がいればご教授お願いします。



環境
FreeBSD 4.7-RELEASE-p27
Apache/1.3.33
PHP/4.3.9
MySQL 4.0.22

参考にしているサイト
http://www.stackasterisk.jp/tech/php/phpMvc01_01.jsp


以下は問題の部分を単純化したプログラムです。
(Model部分は省いています。)

main.php

<?php
require_once("Controller.php");//コントローラークラス
require_once("Request.php");//リクエストを格納するクラス
require_once("Session.php");//セッション変数を格納するクラス
require_once("Result.php");//モデルが返した結果を格納するクラス


$request =& new Request();
$session =& new Session();
$result =& new Result();
$controller =& new Controller($request, $session, $result);
?>
<html><head><title>hoge</title></head>
<body>

<?php

$controller->execute();

?>

</body>
</html>

----------------------------------
//コントローラー

controller.php

<?php
class Controller
{

var $request = null;
var $session = null;
var $result = null;
var $canvasPage = "";


function Controller($request, $session, $result)
{
$this->request =& $request;
$this->session =& $session;
$this->result =& $result;
}


function execute()
{
$this->request->setTitle("テスト");
$this->canvasPage = "view.php";

include_once($this->canvasPage);
}

}

?>

---------------------------------
//このオブジェクトを使用して値を渡したい
request.php

<?php
class Request
{
var $title = "";

function Request() {
//略
}

 //略

function setTitle($title) {
$this->title = $title;
}

function getTitle() {
return $this->title;
}
}


?>

-----------------------------------------
■この部分でエラーが出ます。
view.php

<?php
echo $request->get("testValue");
?>

Fatal error: Call to a member function on a non-object in /usr/local/apache/htdocs/admin/test/view.php
---------------------------------

以上、長々とすみませんでした!!
session.php、result.phpは、今回のエラーと関係ないので省きます。ここ2〜3日ずっとここで足踏みをしています。。

コメント(49)

うまくいきそうです!

ただ、

view.phpの方で、

<?php
global $request;
echo $request->getTitle();
?>


という風に、globalがないと動かないようです。

このサイトを見るかぎりでは、globalはなくても動くようなのですが。。
http://www.stackasterisk.jp/tech/php/phpMvc02_02.jsp#second

それから、
これがコントローラーのクラスなのですが、
http://www.stackasterisk.jp/tech/php/phpMvc01_02.jsp#sixth
ここでは、
function Controller($request, $session, $result)
のままなのですが、なぜここが、
function Controller(&$request, &$session, &$result)
こうすれば上手くいくのか良く分かりませんでした。


お仕事中に申し訳ありません。
返信は、時間があるときで良いですよ〜!
まず、下のソースを見てください。
---------------------------------------------
ソース

01 class Data
02 {
03   var field;
04 }
05 
06 class DataContainer
07 {
08   var data_1;
09   var data_2;
10 
11   // ここで、参照(data_1)とコピー(data_2)が渡される。
12   function DataContainer(&$data_1, $data_2)
13   {
14     $this->data_1 =& $data_1;
15     $this->data_2 =& $data_2;
16   }
17 }
18 
19 $data = new Data();
20 $data->field = 0;
21 $container = new DataContainer($data, $data);
22 $data->field = 1;
23 
24 echo "<div>".$data->field."</div>";
25 echo "<div>".$container->data_1->field."</div>";
26 echo "<div>".$container->data_2->field."</div>";

---------------------------------------------
結果

 1
 1
 0

---------------------------------------------
インスタンスって言葉分かりますか?

ここでいうと、
$dataと$container->data_1が同じインスタンス。
$dataと$container->data_2はまったく別のインスタンスになります。

「インスタンス=オブジェクトの入れ物」だと思ってもらえればいいです。

ここで、ポイントは、
12行目で$data_2は$dataを完全にコピーしたものであるということ
だから、$data_2をグローバル変数$dataそのものであるかのように扱うことができるのです。

しかし、22行目のようにグローバル変数が直接書き換わってしまった場合
同じインスタンスではないので、矛盾が生じてしまいます。

以下は個人的な意見ですが。。。
・クラスの中からグローバル変数を書き換えることはしないほうがいいでしょう
・また、関数にインスタンス変数を渡す場合は参照渡しにしたほうがいいでしょう

急ぎで書いたのでわかり辛いかったら。すんません(><)
このサイト、かなり実践的ですね。
実践的すぎて、初心者には難しすぎるような気もします。

とりあえず、Viewが(パフォーマンスを考慮してか)クラスになってないので、その辺が分かりにくさを助長しているのかも??

きっと、Servletにコンパイルされる前のJSPのイメージなんでしょうね。java使いなら分かりやすいのでしょうか。

私だったら、view.phpを次のように書くかもしれません。

<?php
 require_once( 'result.php' );

 class View {
  var $result = null;
  function View( &$result )
  {
   $this->result = $result;
  }

  function Disp()
  {
?>
<html>

 :

 <?php echo $this->result->getTitle() ?>

 :

</html>
<?php
  }

 }

?>

そして、Controller側でdispXXXXメソッドからでもViewクラスをインスタンス化して、Disp()させます。
 もっと分かりやすく、Viewをクラスじゃなくてfunctionのみにしてもいいかもしれません。
 その場合はview.phpはこんな感じになります。
 Controllerから呼び出すのはクラスにした場合と同じです。

<?php
 require_once( 'result.php' );

 function ViewXXXX( &$result )
 {
?>
<html>
 :

  <?php echo $result->getTitle() ?>

 ;
</html>
<?php
 }
 
?>
>セージロさん

セージロさんの方法で動くようになりました!
参照が上手くいってなかったのと、globalが足りなかったのが原因だったのですね。

このトピックに記載したプログラムは上手く動いていない部分で原因と思わしき部分だけを抜粋したものなのですが、おかげ様でMVC+DAOで書いた方も動くようになりました。

今、結構規模の大きいサイトのシステムを構築しているところで、せっかくだからオブジェクト指向&MVCを勉強して書こうと思ってがんばっていたのですが、徐々に納期も近づいてきてオブジェクト指向はあきらめようか悩んでいたところだったのでとても助かりました!

参考にしているサイトの書き方が間違っていたのかどうかが気になるところですね。あとセージロさんが、「場当たり的な解決策」として、
function Controller(&$request, &$session, &$result) //←ここも参照渡し
と書かれた部分が、どうして「場当たり的」なのかがよく分かりませんでした。無知で申し訳ありません。もしお時間があるときがあれば、いつでも良いので教えてください。

素早いレス本当にありがとうございました。
会ってお礼を言いたいぐらいです!




>アイナリさん

なるほど。分かりやすい御説明ありがとうございます。
プログラムを組んでいると基本的なことがいかに重要かってことをいつも思い知らされます。

参考にしているサイトに関しては、至る所に「//省略」が入っているプログラムで、phpのサンプルデータも置いていないので、自分の組むシステム用に書き直したものを動かしていたところでした。
>12:セージロさん

かなり分かりやすかったです!
だいぶ理解が深まったような気がします。
ただ、試しにセージロさんが書いてくれたものを動かしてみたのですが、
Parse error: parse error, unexpected T_STRING, expecting T_VARIABLE in XXXXX/test.php on line 5
というエラーが出ました。
line 5 は、var field;  の行です。
なぜでしょう。。


>13:chikuraさん

そうですね。かなり難しかったですが、なんとか動く段階まで持ってこれました。
VIEWの部分に関しては、smartyなども紹介されていました。また、resultの部分にある程度のメソッドを持たせるのもアリというようなことも書いてあったように思います。
今回はsmartyをインストールしたり、使いこなす自信があまりないのと、自分でオブジェクト指向で書いてみたいというのがあるので、chikuraさんの書いてくれたようなプログラムも参考にしつつ書いていきたいと考えています。
どうもありがとうございました!



>だんごねこさん

Mojaviも名前は見たのですが、まだ詳しく調べていません。
今度また調べて見ます!
ありがとうござます!
12 で、セージロさんが書いてくれたプログラムのエラーなのですが、
同じようなエラーが、MVC+DAOで組んだほうでも、「ときどき」出ます。

Parse error: parse error, unexpected T_STRING, expecting T_VARIABLE in XXXXX/test.php on line 5

unexpected T_STRINGで検索をかけたところ、以下のようなページがひっかかりました。
「Parse errorについて」
http://ns1.php.gr.jp/pipermail/php-users/2005-January/024608.html
「リロードすると直るParse errorについて」
http://ns1.php.gr.jp/pipermail/php-users/2005-March/025317.html
「何も無い行でUnexpected characterエラーが出てしまいます。」
http://ns1.php.gr.jp/pipermail/php-users/2004-August/023557.html

等、
php.iniあたりが怪しいので、後で調べてみます。
12で出たエラーですが、

var field;



var $field;

にしたらなおりました!
お騒がせしてすみませんでした。

ただ、17で書いた、「ときどき」エラーが起こるというのは原因不明のままです。なぜ「ときどき」なのでしょうか。
ちなみに、

Parse error: parse error, unexpected T_STRING, expecting ',' or ';' in XXXXX/Result.php on line 4

Parse error: parse error, unexpected '(', expecting ',' or ';' in XXXXX/Request.php on line 4

Parse error: parse error, unexpected ';', expecting ')' in XXXXX/Result.php on line 4

こんな感じのエラーがときどきランダムにでます。
エラーの出現率は比較的低い(20〜30回リロードして1〜2回ぐらい)ですが、「ときどき」、しかも、「ランダム」に出てくるので困っています。

とりあえず、今日はそろそろ寝ます。
コメントくださった皆さんどうもありがとうございました!
>> 18

> var field;
>
> を
>
> var $field;
>
> にしたらなおりました!

コーディングミスがありましたか…orz
ごめんなさい(><)
>> 19
おもしろい現象ですね♪(不謹慎)

この現象はスクリプト自体が文字化けして発生するようです。
php.iniのmb_string系の設定を変えてみてください。

リーダーの友達さんのphp.iniの内容(見せてもいい箇所)を貼り付けてみたらどうでしょうか?
お答えできるかもしれません。

下記のサイトにphp.iniの設定例がありましたので調べてみてください。

(ノд) < なせばなる♪

■参考にしたURL
http://benjamin.ddo.jp/modules/newbb/viewtopic.php?forum=2&topic_id=143

>> 14
> どうして「場当たり的」なのかがよく分かりませんでした。

場当たり的と書いたのは
「設計を直したほうがいいですよ☆もし、この設計でいくならここを直してください」
という意味です。

設計についてはもっとふかーい話になるので今は敬遠で(^^;;
どうもです、php.iniなどの設定見ておきますね!

なんとなくですが、まだデータベースからEUCで受け取ったデータをShiftJISに変換するメソッドをDAOの中に追加していないのが原因なような気もしてきました。


>> 14
> どうして「場当たり的」なのかがよく分かりませんでした。

>場当たり的と書いたのは
>「設計を直したほうがいいですよ☆もし、この設計でいくならここを直してください」
>という意味です。

なるほど。
グローバルな変数をクラスの中から操作しないほうが良いとなると、今回のプログラムでは、$request,$session,$resultのグローバルな変数に、クラス内から操作しているのが設計上良くないということでしょうか?


>設計についてはもっとふかーい話になるので今は敬遠で(^^;;


はい(^^)
>21:セージロさん

php.iniをダウンロードして、編集したものをアップロードしようとしたのですが、アクセス権に問題があるなどといわれて、アップできませんでした。

php.iniがあるディレクトリは、
/usr/local/lib
で、php.iniの所有者がrootになっていました。
rootユーザでログインしていないのが問題なのでしょうか?

ただ、rootでログインしようとしても、FTPでつながらないのでよく分かりませんでした。サイトマネージャには、rootとそのパスワードでログインできたので、パスワードが間違っていることはなさそうです。
仕事疲れた(><)
いや。設計がまずいっていったのは、MVC自体のことではないですよ。
ただ、ひとつの同じインスタンスが二通りの参照の仕方をしていたので
将来的に、保守しにくいだろうなぁと思っただけです(><)

だからといって、view.phpに$this->を書くと今度はview.phpの再利用性が失われてしまいますよね。
お勧めの書き方としては、include_once文の前でローカル変数$requestを定義し、
そこに参照を渡すのがいいかと思います。

MVC自体はすごくいい設計だと思いますよ(^^;;


>> 23

LINUXはそんなに得意じゃないですけど…。
自分でサーバを管理してらっしゃるんですか?

管理している人に聞いてみるのが一番早いですよ(〃д〃)?
>渚さん

いえいえ、どんどん横から入ってください!
人によって書き方が違って面白いですね。
大変勉強になります。
渚さんの書き方はスッキリしていて分かりやすそうですね。



>セージロさん

お仕事お疲れ様です。
>お勧めの書き方としては、include_once文の前でローカル変数$requestを定義し
今度試してみますね。

>>23について

php.iniは結局操作できませんでしたが、問題のRequest.phpと、Result.phpを色々いじったら治ったっぽいです。どうやら、参考にしているサイトのコードをコピペしたときに、タブではなく、スペースが大量に混入していたのがまずかったみたいです、スペースを全部取り払って、タブに直して書き直したらエラーが起こらなくなりました。(何故かはよく分かりませんが。)

サーバに関しては、クライアントがVSTサーバを使っていて専用サーバみたいなもんなので、一応php.iniなんかの設定ファイルも操作できるはずなのですが、ちょっと僕の知識ではその方法がよく分かりませんでした。しかもVSTサーバなので、phpのインストールなど分かるよね?っていうノリなので、管理者には聞きにくい&サーバの契約者がクライアントなのでそれもまた面倒なところです。
いまさらなんですが、今日遭遇した現象を報告します。(それともPHPマニュアルを熟読してればいいのかな?)
PHP4.3.11p1とPHP5(マイナーバージョン失・・・念)で&の要不要が違いました。

class Controller {
  var $result;

  function Controller($result) {   *****
    $this->result =& $result;
  }

  function setValue($val) {
    $this->result->setValue();
  }
}

class Result {
  var $value = 0;
  //一部略
  function setValue($val) {
    $this->value = $val;
  }

  function getValue() {
    return $this->value;
  }
}

------
$result = & new Result();
$ctrler = & new Controller($result);
$ctrler->setValue(1);
echo $result->getValue();
------


上記のスクリプトの結果は
PHP4.3.11p1:
  0

PHP5 :
  1

となります。
***** の部分を   |
          v
function Controller(& $result ) {
とするとPHP4.3.11p1でも実行結果が1となります。
個人的には
function Controller( $result )
の方が自然だとおもうのですが、どうでしょうか。
なお、PHP5では、メンバ変数の宣言は var ではなく protected です。
初めまして。
古いトピを引っ張り出してしまいましたが・・・。
こちらで参考にされているサイトと同じサイトを参照しながら自分で勉強しています。つまづいてしまったのでこちらで質問させて頂こうかと思い書き込みしました。

サーバ環境(ロリポップです)
Redhat系 Linux
Apache 2.x
PHP/ver.5.2.6
MySQL(バージョン4.0.24)

参考にしているサイト
http://www.stackasterisk.jp/tech/php/phpMvc01_01.jsp


私の場合、resultを使わずにやってみているのですが、「VO集約用クラス」とあるところでつまづいています。

User.php
<?php
class User {
var $id;
var $name;
var $mail;
var $password;
var $birthday;

// 各属性の set/get メソッド。省略
}
?>

UserList.php
<?php
class UserList {
var $list = Array();
function add($element) { $this->list[] = $element; }
function get($index) { return $this->list[$index]; }
}
?>

UserListクラスをセッションに格納しておき、表示する際に取り出します。
userRegistConfirm.php
<?php
$u = new User();
//↓User型のオブジェクトとしてNULLが返ってきます
print var_dump($u).'<br />';

$u = $UserList->get(0);
//↓array型のオブジェクトが返ってきます
print var_dump($u).'<br />';

//↓本来ここを表示させてセレクトメニューにしたいのですが
$str = $u->getName();
//↑ここで下記のエラーになります。
print $str;
?>

エラー内容です。
Fatal error: Call to a member function getName() on a non-object in /userRegistConfirm.php on line xx

selectメニューのHTML等はとりあえず省略させて頂きましたが、なんとなくですがUserListクラスで返しているオブジェクトがArrayなのでUserクラスのgetterが呼べないのかな、と認識しています。しかし、この先どうやったらgetterが動くようになるのか・・・。もう丸3日悩んでいます(汗)

resultを使っていないことが原因なのでしょうか?
取り急ぎ動作の確認やMVCのフローが知りたかったので動くものを作ること優先にしていたのですが、堂々めぐりになってしまいました。

もしお気づきのことがありましたらぜひコメントをお願いします!!
m(__)m
>みやさん

早々にご返信ありがとうございます。
おっしゃる通り配列をaddしていました・・・。orz
勘違いで違うものを格納していたようです。

$user = new User();
$userList = new UserList($user);
while ($data = $res->fetchRow()) {
 $user->setId($data['id']);
 $user->setName($data['name']);
 $user->setMail($data['mail']);
 $user->setPassword($data['password']);
 $user->setBirthday($data['birthday']);

 //↓ここを$userList->add($data);に書き間違えていました。
 $userList->add($user);
}

そして、UserListクラスにUser型をaddした場合、自動的にUser型に振り分けてくれることを期待していたのですが、stdClassのオブジェクトが返ってきてしまったので、$elementを一度明示的にUserクラスとして変数に入れてからgetすることでUser型のオブジェクトがきちんと返ってくるようになりました。もっと良い方法がきっとおありだとは思うので、更にアドバイス頂けたら幸いです。

とり急ぎ希望した通りの動きにはなりました!
素晴らしいアドバイスをありがとうございました!

UserList.php
<?php
class UserList{
var $list = Array();
function add($element){
$user = new User();
$user = $element;
$this->list[] = $user;
unset($user); }
function get($index){
$user = new User();
$user = $this->list[$index];
return $user;
unset($user); }
}
?>
がると申します。
「今、MVCでシステムを組もうとしているのですが、オブジェクトを使用して値を受け渡すところで、行き詰っています。」という#0の発言だけをみて書き込みをしているのですが。

私の自作フレームワーク「MagicWeapon」では、バッグ(bug)という名前で実装しているのですが。
map系のクラスを作って。
コントローラにそのインスタンスをもって、Modelにはそのreferer(参照)を渡して回ると、簡単に持ち回りが可能だと思います。

>みやさん
あっ、ご近所さんのようですね。ちょっと驚きました。土日は子の世話で駆けずり回っているのでなかなかご返信出来ずすみませんでした。
私は最近Webエンジニアを目指し始め、試行錯誤してようやく今回PHPの仕事が回ってきそうなのです。現在はそのための予行演習中です。あまりまともな開発経験がないので、四苦八苦しています(汗)。そんな中、コードへのアドバイス本当に感謝しております。

はじめはUserListのコンストラクタにクラス名を突っ込むことで、UserListクラスを別のxxxListとして再利用したかったのですが、gettypeでUser型かどうかの判断が出来ないようで(Objectということしか返り値が返ってきませんでしたので)、各モデル(User、その他)ごとにListを作る方法に変更しました。なので

$userList = new UserList($user);

ここの記述は単純に消し忘れていたようです(汗)。
UserListのaddとgetももう少し簡略化出来るよう試してみます!

>がるさん
refererを渡す!なるほど、そういう方法もあるのですね?勉強になります・・・。ありがとうございます。そうするとセッションにいちいち出し入れしなくて済むのでしょうか?勉強不足ですみません。


また新しい質問なのですが、参考サイトの記述だと、前のページから次のページへ移行するまでの間のControllerをどのタイミングで呼べば良いのかわかりにくく、通常どうするものなのか伺いたいのですが・・・。
たとえば、ページ遷移を
「index.php」→「UserRegistForm.php」
と考えている場合、「index.php」のformからPOSTで呼ぶのは「UserRegistForm.php」なのでしょうか?参考サイトでは「Controller.php」を1つだけ持ってページ遷移のfowardに相当する役割をさせるようですが、通常は1つのViewに1つのControllerかな?と考えており、都度ページに対応したControllerを読み込ませるつもりでいるのですが、そんな感じで良いのでしょうか?参考サイトでは「main.php」を使っていますが、このmain.php自体はどこから呼ばれるのだろうかと・・・。
もしかしたら、「index.php」のformからPOSTで呼ぶのは「Controller.php」なのかしら?と考え始めたらそんな気もしてしまい・・・。周囲にPHPに(というかWebにすら)詳しい人が皆無なので社内でアドバイスを受けることは不可能なのです。

お手数で申し訳ありませんが、お手すきの時にでもアドバイス頂ければ幸いです。よろしくお願い致します。
がるです。
あ…先に。
徹夜モードの仕事の合間にかいてるので、変なtypoあったらごめんなさいです orz

To ひなたぼっこ☆さん#35
> ありがとうございます。そうするとセッションにいちいち出し入れしなくて済むのでしょうか?
んと。
HTTPが基本「1往復使い切りの紙芝居」ってのはOKですよね?
で。
n往復で情報を持ち回りたい場合、セッションは不可欠です。
性能とかを考えなければ、バッグのインスタンスをシリアライズして、文字列を格納すると楽ですけどね。

> また新しい質問なのですが、参考サイトの記述だと、前のページから次のページへ移行するまでの間のControllerをどのタイミングで呼べば良いのかわかりにくく、通常どうするものなのか伺いたいのですが・・・。
「通常」という言葉には自信がないのですが。
私の場合の見解を。

前提:
1サイト内に、複数のPageがあるとします(まぁ当然ですね)。
MVCではない場合、n個のPHPプログラムがあろうかと思います。

んで:
コントローラは、1サイトあたり1つ(厳密には、ユーザ側で1つ、管理画面で1つ)です。
また、viewも…理由があれば切り替えますが、大抵1サイトあたり1つです。
で、modelが、n個あります。

コントローラでは、引数に応じて「このmodelをnewしてcallして」という処理をしています。
で…私のフレームワークの場合。
・あるmodelの処理の結果、viewに行かずに「別のmodelをcallしたい」
なんてケースがありまして。
このときに、上述のbagオブジェクトをrefererで持ち回ってます。

…って説明で通じますでしょうか(苦笑
>がるさん、みやさん(まとめて返信ですみません。)

なるほどなるほど、ご親切にありがとうございます(涙)。
ControllerやViewについては認識を改めます。これまでは

index.php→indexController.php→userRegistForm.php→userRegistControll.php→userRegistCheck.php→userRegistCheckControll.php・・・

と考えていました。

index.php→Controller.php→main.php(userRegistForm.php表示)→Controller.php→main.php(userRegistCheck.php表示)→Controller.php・・・

と、1つのサイトにつきController.phpを1つ設けて、そこでmain.phpのページ表示切替をさせる、ということですよね。参考サイトの読み込みもまだ足りていませんね。

「下記の内容でユーザ登録を行います。よろしいですか?」と表示されている「main.php」が、「index.php」から入力された内容をPOSTで受け取っているとします。その際、「index.php」の<form>タグには行き先をどこに指定したらいいのかがよく分かりません。

1:
<form action="main.php" method="post">
 <input type="xxx" name="id" ・・・ />
 <input type="xxx" name="name" ・・・ />
 <input type="xxx" name="mail" ・・・ />
 <input type="xxx" name="password" ・・・ />
 <input type="xxx" name="birthday" ・・・ />
 <input type="submit" name="user" ・・・ />
</form>

とするのでしょうか?それとも

2:
<form action="Controller.php" method="post">・・・</form>

とするのでしょうか?
1:の場合、Controllerクラスをnewしてexecute() メソッドを呼ぶのは「main.php」の役割と思っているのでこうなるのかな?と思うのですが、「Controller.php」をすっとばしている感じがしてキモチワルイのです。

2:の場合は「Controller.php」を「index.php」がnewしなくてはならないのでしょうか?POSTで「Controller.php」が受け取って、「Controller.php」のexecuteメソッドを呼ぶのはどのクラス??などと混乱してきてしまい・・・。

参考サイトの読み込み&PHPの知識がまだまだ足りないようで、お二人のコメントを5回くらい読んでようやく話について行けそうな感じです。(ついて行けてないかもしれませんが。)本当に申し訳ありません。
うわ…楽しそうな話題ですね。cakePHPをつかっていますがここから話ができるとそれぞれのフレームワークの話も真剣にできていいです。
最初から読んでないので最初から読んでまたコメントします。
>渚さん

アドバイスあろがとうございます。
コメント書くのに1時間以上かかってたら渚さんのコメントに気付きませんでした(汗)

>これは
> function add($element) {
>  if ($element instanceof User)
>とやるか
> function add(User $element) {
>とやるかでしょうね。

なるほど。勉強になります。
PHPって関数の引数に型を指定出来ないのかと思いこんでました。(恥)
もう少し勉強しなくては、ですね。

>上記サイトのページ遷移はmain.php→main.phpだったと思います。

そうなんです。ついさっきそこに気付きました。少し軌道修正出来て良かったです。


実はここ数日相当悶々としてまして、ほぼ初めての開発案件なのにも関わらずすべて私一人に丸投げされそうな勢いで、夜中泣きそうに(笑)なってました。皆さん親切で本当に救われています。
まだこれからも山がありそうですが、アドバイスを参考に頑張ってみます。
>・・・・ さん

楽しそう・・・ですか?(汗笑)
本来なら何らかのフレームワークを習得した方が開発スピードは上がるのでしょうけど、御覧の通りPHPの文法すらおぼつかない状況で・・・。何かお気づきの点がありましたらアドバイス下さいませ。
> ひなたぼっこ☆さん

いえ…私はフレームワークをきちんと作りたい知りたいという一心でこの業界に戻ってきたので。楽しそうです。

渚さんのご意見、とても素晴らしいのですがオブジェクト指向バカな私にとってはcase文はあまり使いたくないので…

可変クラス(?)呼び出しはできませんかね?
$変数名にクラス文字名をいれ、
$object = new $変数名;
としてクラスをインスタンスかできると思います。
動かす前に変数名がクラスとしてあるかexist関係のメソッドを投げてあげるのも一興かと…toppageのみ別クラス名を定義する必要があります。

もしよければ一度他のフレームワークを読んでみるというのも大切です。読むことでこんなエレガントなことをと驚くかもですし…無駄なことをと泣けるかもです。
でも最近は読む時間もなくなりました。フレームワークを有効活用するためにも…このように書かれるのは大切です。
最近Zend Frameworkの仕様を流用し一部のライブラリをPHP4用に書き直して簡単なフレームワーク構築しました。
一部の設計思想やディレクトリ構成を拝借させて頂いたのでソースコード自体はほぼフルスクラッチです。
納期の問題で新規の環境構築の余裕がなくPHP5で書き直したのでステージングでもちょこちょこエラーでました…。こういう時はamazon ec2使うべきなんですかね。

以下、既出かもしれませんがPHP5 → PHP4への移植でエラーが出がちなところです。
通常PHP5→PHP4ということがありえなさそうなので参考にならないかもしれませんが参考までに(w
(今後のソースコード指摘なんかには役に立つこともあるかも?)

■PHP4では引数の型宣言使用不可
PHP以外のオブジェクト指向言語を使う人にはありがちかもしれませんが
PHP4では以下を利用できません。
>これは
> function add($element) {
>  if ($element instanceof User)
>とやるか
> function add(User $element) {
>とやるかでしょうね。

引数の型宣言とinstanceofはPHP5からの実装だったかと思います。
シングルトンパターン利用のためオブジェクトを引数で渡す事はなかったので、
本当に参考程度にしかならないですが引数の型宣言はarray不可でした (PHP5ではよくあるarray $foo = null)
PHP4ではis_a関数を使用するのが適切でしょうか。(他にも良い方法あるかもしれません)
※PHP5.3からはis_a非推奨

>PHPって関数の引数に型を指定出来ないのかと思いこんでました。(恥)
>もう少し勉強しなくては、ですね。
残念ながらPHP4では型を指定出来ません…、デフォルト引数は指定できますけれども。
他のオブジェクト指向言語経験者は発狂してしまいそうになるのがPHP4のオブジェクト指向です。

■Validator Chain
実装の仕方が悪かったのかもしれませんが、
PHP4ではアローで接続してchainさせることができませんでした。(PHP5では動いてましたが…)
代替手段として取ったのが「一旦変数に代入して…」を繰り返すでした。
細かいところははしょります。

不可だった記述
$validator = new Validator();
$validator = $validator->addValidator(new Validator_Alnum)->addValidator(new Validator_StrringLength);

採用した記述
$validator = new Validator();
$validator = $validator->addValidator(new Validator_Alnum);
$validator = $validator->addValidator(new Validator_StrringLength);

--------------------------------
続きます。
以下は割とメジャーなPHP4とPHP5の仕様の違いですが、

■メソッド、クラス変数でstatic修飾子は使用不可
PHP4でシングルトンパターンを実装する時に問題になるのがこの辺りです。
『static修飾子は変数にしか使用できない』のでシングルトンパターンを実現するには
下記のようにしてやる必要があります。(PEARライブラリが参考になるかも)
function &getInstance() {
  static $instance = null;
  if (is_null($instance)) {
    $instance = new Class();
  }
  return $instance;
}

■public, private, protected関連
publicとprivateはPHP4でも予約語だった気もしますが、(メソッドだけ?)
PHP4ではクラス変数を宣言する場合varを使用

■final使用不可
PHP4では使えないんです。

■interface(implements), abstruct使用不可
小規模な開発で意識して使うことはないかもしれないですが、
これも重要。

■const使用不可
PHP5からの実装なので。
個人的にはdefineを一元管理してみるかZend_FrameworkのRegistryクラスのような物を
実装するのが好ましいと思います。

■try ~ catch構文使用不可
元ソースを流用しての書き直しではこいつが2番目にきついです。(なので今回はフルスクラッチ)
1番きついのは…

■マジックメソッド
個人的に1番残念なのはこれが使えないことでしょうか。
使わない人にとっては不要の長物ですけれども。

--------------------------------

設計自体はしてないので0時スタート夜明け前エンドくらいでフレームワーク自体の構築作業は終わりましたが、
PHP5からPHP4に書き直す時の手間がPHP4からPHP5に比べてかなりの負担増でした。

>>トピ主様
お時間あるようでしたらPHP5のソースコードで恐縮ですがZend_FrameworkのZend_Registry、Zend_Session、Zend_Controller_Request_Http辺りは読んでみると面白いかもしれません。
色々解決しそうな気もします。
中身を読んでも意味が分からない場合はお時間かけてしまうのもあれなので今回はスルーで。
PHPフレームワークにも色々ありますが、ライブラリとしてZend_Frameworkは重宝しますので
これからPHP案件こなしていくのであれば読んでおいても損はないと思います。

長文失礼しました。
誤字脱字ありましたらすいません…。
と、よく見たら凄く古いトピックでしたねあせあせ
良く確認せずに長文書いてしまった恥ずかしさで一杯ですが、記念に残しておこうとおもいますw
そういえばこんな事もあったなあと懐かしんでくださいわーい(嬉しい顔)
>・・・・ さん
>可変クラス(?)呼び出しはできませんかね?
>$変数名にクラス文字名をいれ、
>$object = new $変数名;
>としてクラスをインスタンスかできると思います。

上記ですが、渚さんの以下の書き込みに帰結するのではないかと思います。
>…が、このままだとcase文とその後のメソッドがひたすら長くなるのでアクションクラスを作るなど何らかの工夫が必要になると思います。

各フレームワークでその辺りのクラスの名称は違えど(M)VC採用していれば大体のプロセスは同じですしね。
構成は変わりますけど。
> たくさん

ごもっともです!私もその何らかの策をあげたかっただけです。他のデザインパターンを使ってクラス生成を容易にできればとも思います。

MVCにかぎらずですがマーティンファウラー様のいうとおりドメインオブジェクトをきちんと書ける環境作りをしたいと思ってます。MVCは「がら」に過ぎないので…とはいえ…もう負けっぱなしです。
コントローラにドメインロジックを書くかモデルをドメインオブジェクトとして用いるか…そうではなくドメインオブジェクトを別に書きたい〜と思ってならない迷惑な私です。

時代に取り残された感いっぱいです。
>たくさん、・・・・さん
コメントありがとうございます。
私はトピ主ではないうえに、こんな古いトピを引っ張り出されてトピ主さんはさぞご迷惑なことと思います。申し訳ないです。
現状PHP5での開発で落ち着きそうですが、お二人のご意見は今後の開発の参考にさせて頂きます。

ログインすると、残り18件のコメントが見れるよ

mixiユーザー
ログインしてコメントしよう!

Let's PHP 更新情報

Let's PHPのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング