class a { function __construct( $contxt ) { $this->request_index_parameter = array(***): $this->sort( $this->request_index_parameter ); } // ソート public function sort ( $param ) { uksort( $param, function ( $key1, $key2 ) { var_dump( $param ); }); } }
↑のようなclassがあり、sort関数で受けた引数をもとにuksortを実行させたいのですがvar_dumpではnullになってしまいます。
■試した事
親のスコープの変数を参照するには無名関数(クロージャ)を使用すると良いという記述があってトライしてみましたが
期待した結果にはならず...
■備考
PHPver.5.3.3
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
クロージャは、変数を親のスコープから引き継ぐことができます。 引き継ぐ変数は、use で渡さなければなりません。
質問者さんのコード
クロージャ内からはクロージャの外側で定義された変数は見えませんので、質問者さんのコードではnull
になります。
また、$this->sort
を実行しても、$this->request_index_parameter
の値は変わりません。
php
1<?php 2class MyClass { 3 public $request_index_parameter = []; 4 5 function __construct($context = null) { 6 $this->request_index_parameter = [ 7 'John' => ['age' => 30], 8 'Anne' => ['age' => 28], 9 'Kevin' => ['age' => 16], 10 ]; 11 12 $this->sort($this->request_index_parameter); 13 } 14 15 function sort($param) { 16 // 引数で`$param`を渡しているので、`sort`関数内では`$param`を参照できる 17 // => `uksort`の引数に渡せる 18 uksort($param, function ($key1, $key2) { 19 // `uksort`の第二引数のクロージャからすると、 20 // クロージャの外側の状態は見えないので、 21 // `$param`は参照できない。 22 echo sprintf('[MyClass::sort1] %s', json_encode(['param' => $param, 'key1' => $key1, 'key2' => $key2])); 23 echo "\n"; 24 25 return $key1 > $key2 ? 1 : -1; 26 }); 27 28 echo sprintf('[MyClass::sort1] %s', json_encode(['param' => $param])); 29 echo "\n"; 30 } 31} 32 33$myInstance = new MyClass(); 34 35echo sprintf(json_encode($myInstance->request_index_parameter)); 36echo "\n";
plain
1[MyClass::sort1] {"param":null,"key1":"John","key2":"Anne"} 2[MyClass::sort1] {"param":null,"key1":"Kevin","key2":"Anne"} 3[MyClass::sort1] {"param":null,"key1":"John","key2":"Kevin"} 4[MyClass::sort1] {"param":{"Anne":{"age":28},"John":{"age":30},"Kevin":{"age":16}}} 5{"John":{"age":30},"Anne":{"age":28},"Kevin":{"age":16}}
クロージャ内で$param
を参照できるコード
回答の上部の引用にあるように、クロージャ内に変数を引き継ぐにはuse
を使います。
ただ、この状態でもsort
関数は実行後に引数の$this->request_index_parameter
を変更しませんし、並べ替え後の値も返しませんので、あまり意味のない関数となります。
php
1<?php 2class MyClass { 3 public $request_index_parameter = []; 4 5 function __construct($context = null) { 6 $this->request_index_parameter = [ 7 'John' => ['age' => 30], 8 'Anne' => ['age' => 28], 9 'Kevin' => ['age' => 16], 10 ]; 11 12 $this->sort($this->request_index_parameter); 13 } 14 15 function sort($param) { 16 // `use ($param)`を追加すると、 17 // クロージャ内で`$param`変数を参照できるようになる。 18 uksort($param, function ($key1, $key2) use ($param) { 19 echo sprintf('[MyClass::sort1] %s', json_encode(['param' => $param, 'key1' => $key1, 'key2' => $key2])); 20 echo "\n"; 21 22 return $key1 > $key2 ? 1 : -1; 23 }); 24 25 echo sprintf('[MyClass::sort1] %s', json_encode(['param' => $param])); 26 echo "\n"; 27 } 28} 29 30$myInstance = new MyClass(); 31 32echo sprintf(json_encode($myInstance->request_index_parameter)); 33echo "\n";
plain
1[MyClass::sort1] {"param":{"John":{"age":30},"Anne":{"age":28},"Kevin":{"age":16}},"key1":"John","key2":"Anne"} 2[MyClass::sort1] {"param":{"John":{"age":30},"Anne":{"age":28},"Kevin":{"age":16}},"key1":"Kevin","key2":"Anne"} 3[MyClass::sort1] {"param":{"John":{"age":30},"Anne":{"age":28},"Kevin":{"age":16}},"key1":"John","key2":"Kevin"} 4[MyClass::sort1] {"param":{"Anne":{"age":28},"John":{"age":30},"Kevin":{"age":16}}} 5{"John":{"age":30},"Anne":{"age":28},"Kevin":{"age":16}}
$this->sort
実行後に引数の値を変更するコード
sort
関数の引数を参照渡しにすることで、関数実行後に引数に変更を反映することができます。
php
1<?php 2class MyClass { 3 public $request_index_parameter = []; 4 5 function __construct($context = null) { 6 $this->request_index_parameter = [ 7 'John' => ['age' => 30], 8 'Anne' => ['age' => 28], 9 'Kevin' => ['age' => 16], 10 ]; 11 12 $this->sort($this->request_index_parameter); 13 } 14 15 // `sort`関数の引数を参照渡しにする 16 function sort(&$param) { 17 uksort($param, function ($key1, $key2) use ($param) { 18 echo sprintf('[MyClass::sort1] %s', json_encode(['param' => $param, 'key1' => $key1, 'key2' => $key2])); 19 echo "\n"; 20 21 return $key1 > $key2 ? 1 : -1; 22 }); 23 24 echo sprintf('[MyClass::sort1] %s', json_encode(['param' => $param])); 25 echo "\n"; 26 } 27} 28 29$myInstance = new MyClass(); 30 31echo sprintf(json_encode($myInstance->request_index_parameter)); 32echo "\n";
plain
1[MyClass::sort1] {"param":{"John":{"age":30},"Anne":{"age":28},"Kevin":{"age":16}},"key1":"John","key2":"Anne"} 2[MyClass::sort1] {"param":{"John":{"age":30},"Anne":{"age":28},"Kevin":{"age":16}},"key1":"Kevin","key2":"Anne"} 3[MyClass::sort1] {"param":{"John":{"age":30},"Anne":{"age":28},"Kevin":{"age":16}},"key1":"John","key2":"Kevin"} 4[MyClass::sort1] {"param":{"Anne":{"age":28},"John":{"age":30},"Kevin":{"age":16}}} 5{"Anne":{"age":28},"John":{"age":30},"Kevin":{"age":16}}
投稿2021/11/11 04:44
総合スコア531
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
uksortに$paramは不要なのでわざわざコールバック内から参照する必要はないと思います
こんなことをやろうとしてるのでしょうか?
PHP
1class a { 2 public function sort ( $param ) { 3 uksort( $param, function ( $key1, $key2 ) { 4 return $key1-$key2; 5 }); 6 return ( $param ); 7 } 8} 9$a=new a; 10$b=[3=>"a",2=>"b",4=>"c",1=>"d"]; 11var_dump($a->sort($b));
投稿2021/11/11 04:51
総合スコア116568
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。