#変数を動的に扱いたいなぁってとき
CSVやら配列やらから取得したデータを変数に代入したいなぁと思うケースって稀にないでしょうか。
//csvから取得したデータ
$csvData = "太郎,21,男性";
//配列化
$arrData = explode(",", $csvData);
//各変数に代入する
$name = $arrData[0];
$age = $arrData[1];
$sex = $arrData[2];
書いておいて思ったけど格納先も最初から配列で作成しておけばいいんでは…と思ったのは内緒だ。
上記の例のように変数が3種類だったらなんとかなりそうですが、多数の変数に対して同様に取得データの代入が必要になるケースもあるかと思います。
もっと楽にコードを書く方法がないかなと探したところ、可変変数を使って動的に代入することができることを知りましたので備忘録として投稿します。
#可変変数の記述例
変数名を文字列から動的にセットして扱うことができます。
$test = "aaa"; //普通の変数①
$var = "test"; //①の変数名
echo $$var."<br/>"; //"aaa"が出力されます。
echo ${"test"}."<br/>" //これも"aaa"が出力されます。
echo ${$var}."<br/>" //これでも"aaa"が出力されます。
上記のように$$変数名を値として持つ変数
だったり${変数名の文字列}
として記述することで、対象の変数のように扱うことができます。
$test = "aaa"; //普通の変数①
$var = "test"; //①の変数名
$$var = "bbb"; //代入してみると
echo $$var."<br/>"; //"bbb"が出力されます。
もちろん代入もOKです。
これで最初の例をいい感じに書き直してみると以下のようになります。
//csvから取得したデータ
$csvData = "太郎,21,男性";
//配列化
$arrData = explode(",", $csvData);
//代入先の変数一覧
$vars = array("name", "age", "sex");
foreach($vars as $key => $var){
$$var = $arrData[$key]
}
echo $name."<br/>"; //太郎
echo $age."<br/>"; //21
echo $sex."<br/>"; //男性
変数が3個なので有り難みがないどころか行数増えてますが…対象の変数が増えていけばスッキリするはず…!
#クラスを使った応用
もちろん、インスタンスのプロパティに対しても可変変数は有効です。
class Animal{
public $name = "Taro";
function set($var, $value){
$this->{$var} = $value; //変数にセット
}
}
$animal = new Animal();
echo $animal->{"name"}."<br/>"; //Taro
$animal->set("name", "Jiro");
echo $animal->{"name"}."<br/>"; //Jiro
上記の場合はインスタンスの変数名->{変数名}
といった記述ですね。
また、下記のようにサブクラスのインスタンスから親クラスのメソッドを実行した時、
親クラスのメソッドからサブクラスのプロパティに対しても同様に扱うことができます。
//親クラス
class Animal{
public $name = "Taro";
function set($var, $value){
$this->{$var} = $value; //変数にセット
}
}
//サブクラス
class Dog extends Animal{
public $type = "マルチーズ";
}
$dog = new Dog(); //サブクラスのインスタンス
echo $dog->{"type"}."<br/>"; //マルチーズ
$dog->set("type", "芝犬");
echo $dog->{"type"}."<br/>"; //芝犬
ベースとなる親クラスに共通的に持たせるメソッドから、サブクラス固有のプロパティにアクセスできるのは何か使い道がありそうですなぁ。
#最後に
もうちょっと応用すれば色々動的な処理ができそうです。
ただ、その反面、自由度高すぎて不具合の原因となりそうな怖い部分もあります。
未宣言の変数だろうと作成されてしまうので、isset()
で変数宣言の有無を確認するなどのチェック処理も必要そうです。