• 締切済み

phpでオブジェクト化に挑戦中です。配列がうまく扱えません。

このようなサンプルプログラムを作ってみました どうやら配列がまずいようなのですが、どうすればよいでしょうか。 <?php class TEST2{ var $b1; } class TEST{ var $a1=TEST2; function printout(){ $this->$a1[0]->b1='123 '; $this->$a1[1]->b1='abc '; $this->$a1[2]->b1='DEF '; } } $c = new TEST; $c->printout(); echo $c->$a1[0]->b1; echo $c->$a1[1]->b1; echo $c->$a1[2]->b1; ?> ちなみに出力結果は DEF DEF DEF となりました。 疑問1.なぜ全部同じ結果になるのか 疑問2.配列だと echo $c->$a1[2]->b1; のように、$a1と、$マークがないと動かない。$を取ると強制終了される。 お願いします。へんてこな質問ですみません。

noname#32059
noname#32059
  • PHP
  • 回答数3
  • ありがとう数1

みんなの回答

回答No.3

function TEST(){ $this->a1=array(); $this->a1= new TEST2(); } これではいけません。なぜなら、$this->a1に対して最初に配列変数として利用しようとしているのに 次の行でインスタンス変数として利用しようとしている為です。 (1行目は完全に無視されますね) ですから、$this->a1[0]->b1='123 ';で値をセットしようとすると、 「この変数は配列ではありませんぜ」ってエラーが出ます。 クラス内にある変数配列に対して最大添字を外部で 変化させたいというのなら、 今の形では行えませんね。 <?php class TEST2{ var $b1; } class TEST{ var $a1; function TEST(){ $this->a1=array(); } function NewInstance($i){ $this->a1[$i]= new TEST2(); } function printout($i, $value){ $this->a1[$i]->b1=$value; } } $c = new TEST(); $c->NewInstance(0); $c->printout(0, "123 "); $c->NewInstance(1); $c->printout(1, "abc "); $c->NewInstance(2); $c->printout(2, "DEF "); echo $c->a1[0]->b1; echo $c->a1[1]->b1; echo $c->a1[2]->b1; ?> インスタンスの生成と値のセットを別々に行うなら こんな感じでしょうか。 そうではなくて、強制的に最大添字でインスタンスを生成し、値をセットしたいのなら、 <?php class TEST2{ var $b1; } class TEST{ var $a1; function TEST(){ $this->a1=array(); } function printout($value){ $i = Count($this->a1); $this->a1[$i]= new TEST2(); $this->a1[$i]->b1=$value; } } $c = new TEST(); $c->printout("123 "); $c->printout("abc "); $c->printout("DEF "); echo $c->a1[0]->b1; echo $c->a1[1]->b1; echo $c->a1[2]->b1; ?> こんな感じに。 値のセットをクラス内だけで完結したいのなら、外部で行っている 呼び出し処理をクラス内で関数化し、 外部からは一度その関数を呼ぶとか。 <?php class TEST2{ var $b1; } class TEST{ var $a1; function TEST(){ $this->a1=array(); } function printout($value){ $i = Count($this->a1); $this->a1[$i]= new TEST2(); $this->a1[$i]->b1=$value; } function SetData(){ $this->printout("123 "); $this->printout("abc "); $this->printout("DEF "); } } $c = new TEST(); $c->SetData(); echo $c->a1[0]->b1; echo $c->a1[1]->b1; echo $c->a1[2]->b1; ?> こんな感じに。 PHP5ならクラス内のプロパティ、メソッドに対して スコープ(直接呼出し可能範囲)が指定できますので、 外部から呼び出せないよう制御させたりする事も出来ます。 PHP4ですとそのあたりの定義がちょっと弱い為、 なんでもかんでも呼べちゃいます。 だから作成したプログラムソースを配布する際は ユーザーが意図的に閉鎖的なクラス内の関数や変数を直接呼んだりも出来てしまいます。 3つ目の例ですと、printout()はクラス内で呼んでくれるだけで良いのですが、 外部からも呼べちゃいます。 私もクラス(オブジェクト指向型)については まだまだ勉強中の身ですので、上記くらいの書き方しか思いつきませんでした。 (有用性の有無は関係なく) 他にもっと良い書き方があるのかもしれません。

回答No.2

なんかちょっと分かったかもしれません。 疑問1.  print_r($c->$a1);とした結果、  stdClass Object ( [b1] => DEF ) です。  クラス自体がTEST2ではないですね。  また、$aとしている時点で、TESTのプロパティ$aを見ているわけではありません。  その証拠に、print_r($c->a1);とすると、  「TEST2」という文字列が入っています。  インスタンスも生成されていませんね。  なんかクラス情報が無い時に勝手に読み込まれるクラス なんでしょうかね。stdClassってのは。空クラスみたいな。  print_r($c);とした結果、  test Object ( [a1] => TEST2 [] => stdClass Object ( [b1] => DEF ) ) です。  つまり、$c->a1にTEST2という文字列が含まれています。  また、a1の配列部には未定義時のクラスオブジェクトが入っている。  ($c->$aとした場合の値。プロパティというより、  完全に変数扱いされている)  通常、インスタンスの生成は$a = new classname();  とする必要があるので、クラスのプロパティ値にいきなり  別クラスのインスタンスを持つ事は出来ないみたいですね。  var $a1 = new TEST2();という表記も出来ません。  コンストラクタを利用すべき箇所ですね。  $a1 = TEST2で、TEST2という文字列が入るとは知りませんでした・・・。  あとわけのわからないクラスについても知りませんでした。  わけのわからないクラスに対して配列指定が無視されるのは  何故かわかりません。  クラスとして動いているせいっぽいです。  仮に  $c->$a1->a2 = "abc";  $c->$a1->b2 = "DEF";  とあった場合、  print_r($c)ではクラスの二重構造になりますから。 疑問2.  全ては上手くインスタンスを作れてなかったせいですね。  プロパティa1は初期値で文字列なのに対して  それを関数内で配列化し、さらにTEST2のインスタンスである事を前提に  プロパティb1へ値を入れようとしていた為です。  プロパティa1はインスタンスでは無い為、printout()では  結局何も入れる事が出来ていません。  また先に述べた通り、$a1->~とする事で、わけのわからない  クラスのインスタンスとして扱われています。 なんか説明悪いですが、根源は$this->a1がTEST2のインスタンスでない事です。 $this->a1が配列であり、各添字毎にインスタンスが正しく作られれば、 $c->a1[0]->b1といけるでしょう。

回答No.1

<?php class TEST2{ var $b1; } class TEST{ var $a1; function TEST(){ $this->a1[0] = new TEST2(); $this->a1[1] = new TEST2(); $this->a1[2] = new TEST2(); } function printout(){ $this->a1[0]->b1 = '123 '; $this->a1[1]->b1 = 'abc '; $this->a1[2]->b1 = 'DEF '; } } $c = new TEST(); $c->printout(); echo $c->a1[0]->b1; echo $c->a1[1]->b1; echo $c->a1[2]->b1; ?> これで動きますよ。 違いはコンストラスタとプロパティの値の送受信、 インスタンスの生成時です。 質問のコーディングですと、$aは初期値として インスタンスをセットしているのに、 関数内ではいきなり配列になってます。 TEST2のインスタンスのはずなのに、それに配列は存在しません。 その後からはちょっと私の知識では説明出来ません^^; 摩訶不思議な現象が(笑) この時点で$a[0]~[2]とは別モノ状態(?)のようになってしまい、 動きがおかしくなっているように感じます。 配列はないのに、あたかも配列のように扱おうとして、 でも配列は存在しないから、、、、 うむ、わかりません>< 上記プログラムだと、クラスTESTのプロパティとして$a1の配列が存在し、その存在毎にクラスTEST2をセットしているので正常に動作します。 また、 <?php class TEST2{ var $b1; function TEST2(){ $this->b1 = array(); } } class TEST{ var $a1; function TEST(){ $this->a1 = new TEST2(); } function printout(){ $this->a1->b1[0] = '123 '; $this->a1->b1[1] = 'abc '; $this->a1->b1[2] = 'DEF '; } } $c = new TEST(); $c->printout(); echo $c->a1->b1[0]; echo $c->a1->b1[1]; echo $c->a1->b1[2]; ?> とすれば、クラスTESTの$aにはクラスTEST2のインスタンスが存在し、 クラスTEST2のプロパティとして$bを配列として利用していますから、正常に動作します。

noname#32059
質問者

お礼

回答ありがとうございました array()とコンストラクタについてなんとなくですが、納得できました。先が見えてきました!! もうひとつ質問ななのですが。 $this->a1[]->b1 のようにa1を配列にするにはどのようにすればよいのですか? 配列をひとつずつ $this->a1[0] = new TEST2(); $this->a1[1] = new TEST2(); $this->a1[2] = new TEST2(); のようにすればいいのはわかるのですが、配列の個数が未知のときはどのようにすればよいのでしょうか。 自分なりに 以下のようなプログラムを書いてみたのですが動きません <?php class TEST2{ var $b1; } class TEST{ var $a1; function TEST(){ $this->a1=array(); $this->a1= new TEST2(); } function printout(){ $this->a1[0]->b1='123 '; $this->a1[1]->b1='abc '; $this->a1[2]->b1='DEF '; } } $c = new TEST; $c->printout(); echo $c->a1[0]->b1; echo $c->a1[1]->b1; echo $c->a1[2]->b1; ?> どうやら$this->a1[0]->b1='123 '; の行でエラーがでるようです。 何度もすみません、お願いします。

関連するQ&A

  • PHPにてクラスを配列にすることは可能でしょうか。

    PHPにてクラスを配列にすることは可能でしょうか。 環境はPHP5です。 現在下記のようなクラスを作成しました。 class Ary_c { var $v1; // コンストラクタ function Ary_c() { $this->v1 = "test"; } } このクラスをC++言語などで出来るような、 クラスの配列として扱いたいのです。 C++だとたとえば10個の要素があるクラスの配列は Ary_c t[ 10 ]; みたいな感じで宣言できます。 こういったことをPHPでやることは可能でしょうか。

    • ベストアンサー
    • PHP
  • PHPの配列でわからないことがあるので教えてください。

    PHPの配列でわからないことがあるので教えてください。 例えば以下のような2つの配列$aと$bがあるとします。 $a[0]=a、$a[1]=b、$a[2]=c $b[0]=w、$b[1]=q、$b[2]=b、$b[3]=c これで、$a[1]と$b[2]の中身が同じであることを取得し、さらに$bの配列の添え字の2を返すようにしたいのですが、わかりません。 どのようにプログラムを書けばよいのでしょうか? よろしくお願いします。

    • ベストアンサー
    • PHP
  • クラスの中の配列へのアクセス

    お世話になります。 昨日?に似たような質問をさせていただきましたが、またよろしくお願いいたします。 以下のようなクラスがあります。 (自分で動かして確認したいのですが、今確認する環境がないので申し訳ありませんがご回答お待ちしてます) class Class1{   var $list; // 添字が数値のの配列です   …   function getList(){     return $this->list;   } } $a = new Class1; $a->getList()->[0] ↑上のようなやり方で、Class1の$listの配列の1番目(0番目)の要素を取得したいのですが、これは可能なのでしょうか? 何卒よろしくお願い致します。

    • ベストアンサー
    • PHP
  • phpのfor文の中で配列を作りたいです。

    $a = array(); $a[0]="あ"; $a[1]=""; $a[2]="い"; $a[3]=""; $a[4]=""; $a[5]="う"; のような配列がありfor文の中で文字列が一文字以上だったら配列$bに入れるということをしたいのですが、 $b=array(); for($i=0; $i<count($a); $i++){ $c = mb_strlen($a[$i]); if($c>=1){ $b = $a[$i]; } } var_dump($b); とすると$bには最後の”う”しか入りません。 $bを $b[0]="あ"; $b[1]="い"; $b[2]="う"; とするようにするにはどうしたらいいですか?

    • ベストアンサー
    • PHP
  • kshで配列を使いたい

    kshで配列を使いたいです。 とあるコマンドの結果として、"a b c"のようなスペース区切りの結果を変数に受け取ります。 それを配列として読み込みたく、以下のようにしています。 ******************************************** VAR=`TOARU_COMMAND` # とあるコマンドの結果は"a b c" ARRAY=(${VAR}) ******************************************** redhatのkshではうまくいったのですが、 AIXのkshでは"("でエラーになってしまいました。 どうすれば配列として認識されるのでしょうか。

  • クラスの中のクラスへのアクセス

    お世話になります。 クラスが以下のようにあります。 class ClassName1{ var $classname2_obj; // クラス「ClassName2」のオブジェクト function getClassName2Obj(){ return $this->$classname2_obj; } } class ClassName2{ var $array_list; // 配列です  function getArrayList(){ return $this->array_list; } } やりたいのは、ClassName1のgetClassName2Obj関数でClassName2の配列をgetArrayListで取得したいのです。 $a = new ClassName1; $b = $a->getClassName2Obj(); $c = $b->etArrayList(); 上の$b = … と$c = …の部分の処理を一行にまとめることはできないでしょうか? 何卒よろしくお願い致します。 PHPは5です。

    • ベストアンサー
    • PHP
  • 二つの配列のマッチング

    お世話になっております。 配列$a と $b から配列$cを作りたい。 どうすればいいですか? $a = array('200708', '200709', '200710' ,'200711', '200712', '2000801); $b = array('200710,3', '200712,1'); $c = array('200708,0', '200709,0', '200710,3' ,'200711,0', '200712,1', '2000801,0); または、 $c = array('200708', '200709', '200710,3' ,'200711', '200712,1', '2000801);

    • 締切済み
    • PHP
  • PHPからFlashへの配列の渡し方がわかりません

    こんにちは。 FlashとPHPの連係についての質問です。 どうしてもわからないのでどなたか手を貸してくださると助かります。 PHP側から$a=array("a","b","c")、という配列をFlash側に送ります。 その際、まずHTMLタグの<object>内にはどのように記述すればよろしいのでしょうか? またFlash側でその配列をどのように受け取り、その値を配列に入れたいのですがどのようにしたらよろしいでしょうか?? どなたかお願いいたします。

    • ベストアンサー
    • Flash
  • PHPからFlashへの配列の渡し方がわかりません

    こんにちは。 FlashとPHPの連係についての質問です。 どうしてもわからないのでどなたか手を貸してくださると助かります。 PHP側から$a=array("a","b","c")、という配列をFlash側に送ります。 その際、まずHTMLタグの<object>内にはどのように記述すればよろしいのでしょうか? またFlash側でその配列をどのように受け取ればよろしいでしょうか?? どなたかお願いいたします。

    • 締切済み
    • PHP
  • for文で変数に格納される文字列 (Bシェル)

    シェルの記述に関しての質問です 例えば、 a1 b1 c1 a2 b2 c2 a3 b3 c3 a4 b4 c4 ・ ・ ・ というスペース区切りの配列が書かれたリストファイル(test.lst)を for VAR in `cat test.lst` do set $VAR echo $1 echo $2 echo $3 done という形で処理しようとします。 そうすると、$VAR に入る変数は "a1" や "b1" といった感じで行単位ではなく、スペース区切りで入ってきてしまい、 $2 や $3 はnullになってしまいます。 これを行単位で $VAR という変数に代入する方法はありますか? 区切り文字はスペースのままとします。 宜しくお願いします。

専門家に質問してみよう