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
以下のような質問にはグッドを送りましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
下記のような質問は推奨されていません。
- 間違っている
- 質問になっていない投稿
- スパムや攻撃的な表現を用いた投稿
適切な質問に修正を依頼しましょう。
回答2件
1
クロージャは、変数を親のスコープから引き継ぐことができます。 引き継ぐ変数は、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
総合スコア108937
良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
関連した質問
解決済
回答2
クリップ0
更新
2023/01/24
JavaScript forとsetTimeoutと配列を組み合わせた謎の挙動について
解決済
回答3
クリップ0
更新
2023/01/21
PHPの関数名の後につく「?」の意味について
受付中
回答3
クリップ2
更新
2023/01/24
乱数の一桁目が1に偏ってしまう
受付中
回答1
クリップ2
更新
2023/01/29
jsとgasによるdoPostとfetch間によるhtmlファイルの受け渡しについて
解決済
回答1
クリップ0
更新
2023/01/29
googleスプレッドシート、ピポットテーブルのフィルターを変更するには?
解決済
回答1
クリップ1
更新
2023/01/28
スクロールバーの動きについて(イベントが何度も処理させたい
解決済
回答2
クリップ1
更新
2023/01/28
axiosを用いたAPI呼び出しで"blocked by CORS policy"で呼び出し失敗
受付中
回答2
クリップ1
更新
2023/01/28