• ベストアンサー

ハッシュのリファレンスを戻り値にしたい

PHPでハッシュのリファレンスを戻り値にする方法が知りたいです。 perlでは return \%hash; ですが、phpではどうなるのでしょうか? 他に別の方法があるのでしたらそれでも構いません。

  • ne5
  • お礼率4% (5/124)
  • PHP
  • 回答数2
  • ありがとう数0

質問者が選んだベストアンサー

  • ベストアンサー
  • xpector
  • ベストアンサー率75% (3/4)
回答No.2

Perlのリファレンスに似た機能としてPHPには「参照」というものがあります。 例えば、 $a = 1; $b =&$a; // $aと$bは同じ値を指すようになる($aが保持する値に$bという変数名でアクセスできる) $b = 2; //$aの値も2になる echo $a . "," . $b; これは、Perlで似たようなことをするとしたら以下のコードになります $a = 1; $b = \$b; // $$b = 2; print $a . "," . $$b; で、関数が参照を返すようにするためには、定義する関数名の前に&をつけ、かつ関数の戻り値を代入する際にも関数名の前に(=の後ろに) & をつければよいです。代入の際に&を記述し忘れるとダメです。 $hash =& funcA(); function &funcA() {  $hash = array();  $hash['key'] = 'hoge';  return $hash; } 実際に参照を返しているか以下のコードで確認してみてください。 <?php // [参照返し版] 関数内部で保持するstaticハッシュ$aryに // 要素を1つ挿入しその参照を返す function &funcA() {  static $ary = array();  static $i=0;  $ary['key'.$i] = '$val'.$i;  $i++;  return $ary; } // [通常版] 関数内部で保持するstaticハッシュ$aryに // 要素を1つ挿入しその配列を返す function funcB() {  static $ary;  static $i=0;  $ary['key'.$i] = '$val'.$i;  $i++;  return $ary; } echo "<pre>"; $aryA =& funcA(); $aryA['test'] = 'test'; $aryA =& funcA(); print_r($aryA); // 結果 A //Array //( // [key0] => $val0 // [test] => test // [key1] => $val1 // ) $aryB = funcB(); $aryB['test'] = 'test'; $aryB = funcB(); print_r($aryB); // 結果 B //Array //( // [key0] => $val0 // [key1] => $val1 // ) 単純な値を保持しているような配列ではあまり効果は無いかもしれませんが、PHP4において関数内部で生成したオブジェクトを返す際に、オブジェクトの参照を返したいことも生じると思うので覚えておいて損は無いかもしれません。PHP4で関数で単にオブジェクトを返すとオブジェクトのコピーが返されることになります。 http://www.shigeweb.jp/php/project_p/?section=php5oop&page=substitution PHP5の場合は勝手に参照渡し・参照返しをしてくれると思うので、あまり上記方法を取ることもないでしょう。 以下のページもPHPにおける参照の挙動について参考になるかもしれません http://www.sound-uz.jp/php/test/first2.html

その他の回答 (1)

  • hrm_mmm
  • ベストアンサー率63% (292/459)
回答No.1

php の場合、global宣言しないローカル変数は、そのスコープを抜けると実体が無くなるのでリファレンスを返してもリファレンスの示す先の実体は消えるので、エラーになるんでなかったかな?よって、配列全体を返せばいいはずだけど。 function f(){ $ary = array(1,2,3); return $ary; // この$aryをリファレンス&$aryにするとエラーになる } $res = f(); print_r($res); これで、十分だと思うのだけど、なにかリファレンスでないといけない理由でもありますかね? 引数でリファレンスを渡して、元の配列を直接変更することは出来ますが、php4.3では、Warning: が出ます。あまり推奨される方法ではないということです。 function f2($ary){ $ary[0] = 1; } $orgary = array(); f2( &$orgary ); print_r($orgary); 通常は、ローカル変数に引き渡して、変更したものを再度返して代入し直します。 function f3($ary){ $ary[0] = 1; return $ary; } $orgary = array(0,1,2); $orgary = f3( $orgary ); print_r($orgary); 配列操作関数は大概この方法を取っています。

関連するQ&A

  • ハッシュのリファレンスを用いた処理

    ActivePerl 5.8 , WinXP SP2の環境です。 Perl スクリプトを用い、ファイルから複数のブロックからなる情報をよみとり、個別のハッシュを作り、それをリファレンスの配列としてまとめて後から参照するという操作をしたいのですが、詰まってしまいました。。 例として読み取るファイルは ---input.txt--------- >1 Jan 1 Feb 4 >2 Mar 9 Apr 3 >3 Oct 8 Nov 4 ------------------ ここから1,2,3の個別のハッシュ {Jan => 1 Feb => 4} {Mar=> 9 Apr =>3} {Oct =>8 Nov =>4} を作成し、それぞれのハッシュのリファレンスの配列をつくり、その後からすべてのハッシュの中身を個別に出力させたいと思いました。 次のようなスクリプトを作成したのですが思ったように作動しません。 use strict; open (IN, "input.txt") or die ("cant open file \n"); my $reff; my @array_of_reff; my %hash; my $count = 0; while(<IN>){ my $line = $_; ######ここでは各ブロックの頭の ">"を認識し、2個目以降であれば直前までで作ったハッシュのリファレンス($reff)を配列@array_of_reffに入れる。 if($line =~ /^>/){ if($count >0){ $reff = \%hash ; push (@array_of_reff, $reff); %hash = (); } $count++; } ########ここではアルファベットが入った行を認識して、ハッシュに追加しています if($line =~ /^[A-Za-z]/){           $line =~ /([A-Za-z]+)\s+/; my $month = $1; $line =~ /\s+(\d+)/; my $day= $1; $hash{$month} = $day;     } ###ここはファイルの最後になったら直前まで作っていたハッシュののリファレンス($reff)を配列@array_of_reffに入れる。 if( eof ){ $reff = \%hash ; push (@array_of_reff, $reff); } } #####ハッシュのリファレンスの配列(@array_of_reff)からもとのハッシュを参照し、ハッシュごとに出力 foreach my $reff_of_hash (@array_of_reff){    print "output";    while( (my $key,my $value) = each %$reff_of_hash ){     print "\n" , $key, " : ", $value, ;    } } このスクリプトを実行すると Nov 4 Oct 8 という3つめのハッシュのなかみが3回出力されてしまいます。自分では3つの別のハッシュをつくっているつもりでも、どうやら1種類しか作れていない、もしくはハッシュが上書きされているようなのですが、原因がわかりません。 この例だけ見るとハッシュのリファレンスを使う必要はないのですが、実際にはもうすこし大きいスクリプトで"ハッシュのリファレンスの配列を他のサブルーチンに渡す"ということを想定しており、これが解決できず先に進めない状態です。 アドバイス、解決法がわかったら教えていただけないでしょうか。

    • ベストアンサー
    • Perl
  • リファレンスをサブルーチンの戻り値にしてもOKですか?

    ■ サブルーチン内部で処理した結果を格納した、配列、ハッシュ、スカラーなどのデータを戻り値として利用する必要があります。その場合、どうするのが標準的なやり方でしょうか? ■ return (配列へのリファレンス, ハッシュへのリファレンス, スカラー); などとやってしまっても問題はないでしょうか? ■ 下のプログラムを試したところ、予想に反しちゃんと 「31415」と表示されました。 #!/usr/bin/perl -w sub subroutine{ my @a = (3, 1, 4, 1, 5); return \@a; } my $b = subroutine{}; print @$b; ■ サブルーチン内部で使用した変数へのリファレンスをサブルーチン 外で使っていいのだろうか? サブルーチンの処理が終了した時点でサブルーチン内部で使用した 変数はメモリーから消去されるのかと思ったものですから。

    • ベストアンサー
    • Perl
  • ハッシュリファレンスの無名変数

    サブルーチンにハッシュリファレンスを渡すために、 以下のようにすると上手く実行されます。 %hash = ( baa => 1, boo => 2 ); test(\%hash); sub test { my %hash = %{shift}; print $hash{baa}; } これを、%hashに格納せずに、 直接渡そうとすると上手くいきません。 test(\( baa => 1, boo => 2 )); 考え方が間違っているのでしょうか。

    • ベストアンサー
    • Perl
  • Perlは戻り値で、ハッシュや配列を正しく返さないのでしょうか?

    Perlは戻り値で、ハッシュや配列を正しく返さないのでしょうか? 返せるように見えて実際は、歯抜けのデータなど、不安定で使い物になりません。 よって、リファレンスでスカラー値で利用するのが正論でしょうか? $a = ''; %b = (); @c = (); ○ return ($a, \$b, \$c); × retuen ($a, %b, @c); ○ my ($a, $b, $c) = aru_kansuu($hikkey, ('komori')); × my ($a, %b, @c) = aru_kansuu($hikkey, ('komori'));

    • ベストアンサー
    • Perl
  • ハッシュの中身の表示

    ハッシュの中身の確認ができなくて困っています。 下記のような実行文においてです。 当然、test の戻り値は、スカラーとハッシュです。ハッシュを戻すときには参照渡し記号の\もつけています。 my ($return_code, %hash_data) = test(); 表示しようとすると、 Hash(0x5b04) のような表示にしかなりません、、 (試した表示方法は、下記4つです。) (環境は、WindowsXP上での、ActivePerl-5.10.0.1004 です。) foreach $key ( keys( %Hash ) ) { print "キー値 : $key\n"; print "値 : $Hash{$key} \n " } while ( ( $key , $value ) = each %Hash ){ print "キー値 : $key\n"; print "値 : $value \n " ; } use Data::Dump qw(dump); print dump(\%hash); #print %display_test; 宜しくお願いします。

    • ベストアンサー
    • Perl
  • 二次元ハッシュの引き出し方について

    2次元のハッシュをObjectを用いて作り、以下の様に第一キー固定で第二キーを取り出したいです。 ----------------------------------------------------------- hash = new Object; hash[3] = new Object; hash[3][1] = 3; hash[3][2] = 6; hash[3][3] = 9; for (key in hash[3]){  _root.debug+=key; } ----------------------------------------------------------- 上記は上手く動かないので、以下の様に修正しました。 ----------------------------------------------------------- hash = new Object; hash[3] = new Object; hash[3][1] = 3; hash[3][2] = 6; hash[3][3] = 9; tmp=hash[3]; for (key in tmp){  _root.debug+=key; } ----------------------------------------------------------- いったんtmpに代入する事で期待通りの結果が得られましたが、スッキリしません。 Perl等の他言語では、「無名ハッシュ」という概念を表記化することができるので、Actionscriptでも良い表記方法がありましたら教えてください。 ※オーサリングルールはParaFla! ActionSctiptは1.0相応です。

  • Ruby 2次元のハッシュ

    Rubyで2次元のハッシュを扱いたいです。 perlで書くと以下のような感じです。(最近perlに疎遠なので自信無いですが^^;) hash{$key1}{$key2}=$value; foreach $key1 (keys %hash){ foreach $key2 (keys %{$hash{$key1}}){ print "$hash{$key1}{$key2}\n"; } } Rubyだとどんな感じになりますか?

  • phpのパスワードのハッシュ化について

    phpで会員サイトの作成を学習しています。 PDOを使用してMysqlサーバーに接続しています。 開発環境はxamppでphp Version 5.5.15を使用しています。 入力フォームにユーザーの情報を入力してもらい、 データベースに格納する際、 基本的なセキュリティ要件として パスワードをハッシュ化する必要があるということを こちらのサイトで(http://php.net/manual/ja/faq.passwords.php) 知りました。 ハッシュ化については初耳で、いまいちハッシュアルゴリズムの種類による違い等はまだ理解しきれていないのですが、 PHP5.5.15を使用しているので、パスワードのハッシュアルゴリズムは 上記サイトに載っているようにpassword_hashを使用するのが今のところ最善なのでしょうか? また、ハッシュ化されたパスワードの認証についてですが、 ログイン画面でパスワードを認証する際、 ユーザーが入力したパスワードをハッシュ化して 該当レコードのハッシュ化されて保存されたパスワードと 同じであれば認証が成功するという認識で正しいでしょうか? ご回答、よろしくお願いします。

    • ベストアンサー
    • PHP
  • 戻り値について

    ただ今、c言語の勉強をしている者です。 本を読んでいて分からないところがあったので ご指導して頂ければと書き込みました。 それは、最初と最後のところです。 int main(void) { ・ ・ 処理 ・ ・ return 0; >int main(void) このintというのは 戻り値が整数だと言うことだと思うのですが 戻り値が文字の場合ということも あるということですか? 例えば、 char main(void) ということもあるのでしょうか? また、voidというのは 他の名前にしたらいけないのでしょうか? > return 0; というのは、 正常に終わったら戻り値を0にしろということですか? ご指導して頂ければと思います

  • 関数でxml::simpleが使えない。

    AWSがらみで以下のようなことがしたいです。 --------------- my $url = 'amazon web service RESTのURL'; my %XMLtree = xmlget($url); sub xmlget{ my $url = shift; my $content = LWP::Simple::get($url); #xml->hash変換 my $xs = new XML::Simple(); my $XMLtree = $xs->XMLin($content); return $XMLtree; } ----------------------- しかしハッシュを関数の引数や返り値にすると上手く動きませんでした。 そこでreturnで値を渡さずに、globalで%XMLtreeを宣言してXMLinの値を代入しようとしたのですがうまくいきません。 他にもリファレンスを渡してみたりしたのですが上手くいきません。 よく考えたら$XMLtreeはハッシュのリファレンスの塊なので、トップのアドレスを渡しても、関数を抜けてしまえば実体は消えます。(ですよね?) ハッシュのリファレンスの塊である$XMltreeを関数から外側に渡すにはどうすればいいでしょうか? それとも全く別の問題なのでしょうか?

    • ベストアンサー
    • Perl

専門家に質問してみよう