質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.36%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

クロージャ

クロージャは、プログラミング言語における関数オブジェクトの一種です。 引数以外の変数を実行時の環境ではなく、 自身が定義された環境において解決することを特徴とします。

Q&A

2回答

600閲覧

メンバ関数内での変数参照

Ryu__ta

総合スコア15

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

クロージャ

クロージャは、プログラミング言語における関数オブジェクトの一種です。 引数以外の変数を実行時の環境ではなく、 自身が定義された環境において解決することを特徴とします。

0グッド

0クリップ

投稿2021/11/11 03:38

編集2021/11/11 03:41
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ページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2021/11/11 03:50

PHPバージョンが古すぎるのが気になりますが、ひとまず、そのクラスを実行している呼び出し元のコードも提示してください。 ただ、クラス内なら引数にする必要ないような。
yambejp

2021/11/11 03:50

動作が確認できるようなソースになってないようです
melian

2021/11/11 04:37

callback 関数内からは外側のスコープにある変数は参照できませんので use を使いましょう。 uksort( $param, function ( $key1, $key2 ) use ($param) { ...
guest

回答2

0

クロージャは、変数を親のスコープから引き継ぐことができます。 引き継ぐ変数は、use で渡さなければなりません。

PHP: 無名関数 - Manual

質問者さんのコード

クロージャ内からはクロージャの外側で定義された変数は見えませんので、質問者さんのコードでは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

KAOsaka

総合スコア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

yambejp

総合スコア116568

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問