PHP

PHPの配列に戸惑ったので自分なりに整理する

発端

  • 今まで、ある程度仕事で使ったという言語はCとJava(マニアックな業界や、レガシーな業務システム多め)
  • 案件でPHP(FWはCodeIgniter3とslim3)を少し触る機会があり、配列で戸惑った
  • FWを使わない状態で、一旦整理してみたいと思った

環境

Windows 8.1 + XAMPP Version 7.0.24

その1:配列の生成

バージョンによって書き方に違いはあれど、PHPには大きく2種類の配列があるもよう。
* Javaの配列のように、[0]、[1]、[2]…という、「キー=添字」形式
* JavaのMapのように、KeyとValueで値を保持する連想配列形式

そして、この2つは一つの変数内で共存できるようだ。

試してみる

<?php
// 結果出力用
function printValue($v) {
  echo '<pre>';
  var_dump($v);
  echo '</pre>';
}

// 連想配列を初期化
$arr = [
  'key1' => 'value1',
  'key2' => 'value2'
];
printValue($arr);

// 下記が出力される
/*
array(2) {
  ["key1"]=>
  string(6) "value1"
  ["key2"]=>
  string(6) "value2"
}
*/

$arr[] = ['key3' => 'value3'];
printValue($arr);

// 下記が出力される
/*
array(3) {
  ["key1"]=>
  string(6) "value1"
  ["key2"]=>
  string(6) "value2"
  [0]=>
  array(1) {
    ["key3"]=>
    string(6) "value3"
  }
}
*/

$arr[] = ['key4' => 'value4'];
printValue($arr);

// 下記が出力される
/*
array(4) {
  ["key1"]=>
  string(6) "value1"
  ["key2"]=>
  string(6) "value2"
  [0]=>
  array(1) {
    ["key3"]=>
    string(6) "value3"
  }
  [1]=>
  array(1) {
    ["key4"]=>
    string(6) "value4"
  }
}
*/

$arr['key5'] = 'value5';
printValue($arr);

// 下記が出力される
/*
array(5) {
  ["key1"]=>
  string(6) "value1"
  ["key2"]=>
  string(6) "value2"
  [0]=>
  array(1) {
    ["key3"]=>
    string(6) "value3"
  }
  [1]=>
  array(1) {
    ["key4"]=>
    string(6) "value4"
  }
  ["key5"]=>
  string(6) "value5"
}
*/

$arr[2] = ['key6' => 'value6'];
printValue($arr);

// 下記が出力される
/*
array(6) {
  ["key1"]=>
  string(6) "value1"
  ["key2"]=>
  string(6) "value2"
  [0]=>
  array(1) {
    ["key3"]=>
    string(6) "value3"
  }
  [1]=>
  array(1) {
    ["key4"]=>
    string(6) "value4"
  }
  ["key5"]=>
  string(6) "value5"
  [2]=>
  array(1) {
    ["key6"]=>
    string(6) "value6"
  }
}
*/

printValue($arr[0]);

// 下記が出力される
/*
array(1) {
  ["key3"]=>
  string(6) "value3"
}
*/

printValue($arr['key1']);
// 下記が出力される
/*
string(6) "value1"
*/

その2:同じキーが存在する配列をネスト

試してみる

<?php
// 結果出力用
function printValue($v) {
  echo '<pre>';
  var_dump($v);
  echo '</pre>';
}

// 配列初期化
$arr1 = [
  'key1' => 'value1',
  'key2' => 'value2',
  'key3' => 'value3',
];
$arr2 = [
  'key3' => 'value3',
  'key4' => 'value4',
  'key5' => 'value5',
];
$arr1['key3'] = $arr2;
printValue($arr1);

// 下記が出力される
/*
array(3) {
  ["key1"]=>
  string(6) "value1"
  ["key2"]=>
  string(6) "value2"
  ["key3"]=>
  array(3) {
    ["key3"]=>
    string(6) "value3"
    ["key4"]=>
    string(6) "value4"
    ["key5"]=>
    string(6) "value5"
  }
}
*/

printValue($arr1['key3']);

// 下記が出力される
/*
array(3) {
  ["key3"]=>
  string(6) "value3"
  ["key4"]=>
  string(6) "value4"
  ["key5"]=>
  string(6) "value5"
}
*/

printValue($arr1['key3']['key3']);

// 下記が出力される
/*
string(6) "value3"
*/

printValue(array_key_exists('key1', $arr1));
/* bool(true) */

printValue(array_key_exists('key3', $arr1));
/* bool(true) */

printValue(array_key_exists('key5', $arr1));
/* bool(false) */

その3:ArrayObject

http://php.net/manual/ja/class.arrayobject.php
ここを参照すると、「このクラスは、オブジェクトを配列として動作させます。」とのこと。arrayとArrayObjectは、JavaでいうArrayListのような感じでしょうか。

試してみる

<?php
// 結果出力用
function printValue($v) {
  echo '<pre>';
  var_dump($v);
  echo '</pre>';
}

class Charactor {
  public $name;
  public function __construct($name) {
    $this->name = $name;
  }
}

class Team extends ArrayObject {
  public function __construct() {
    $this->append(new Charactor('イレブン'));
    $this->append(new Charactor('マルティナ'));
    $this->append(new Charactor('ベロニカ'));
    $this->append(new Charactor('セーニャ'));
  }
}

$team = new Team();
printValue($team);

// 下記が出力される
/*
object(Team)#1 (1) {
  ["storage":"ArrayObject":private]=>
  array(4) {
    [0]=>
    object(Charactor)#2 (1) {
      ["name"]=>
      string(12) "イレブン"
    }
    [1]=>
    object(Charactor)#3 (1) {
      ["name"]=>
      string(15) "マルティナ"
    }
    [2]=>
    object(Charactor)#4 (1) {
      ["name"]=>
      string(12) "ベロニカ"
    }
    [3]=>
    object(Charactor)#5 (1) {
      ["name"]=>
      string(12) "セーニャ"
    }
  }
}
*/

printValue(count($team));

// 下記が出力される
/*
int(4)
*/

printValue($team[0]);

// 下記が出力される
/*
object(Charactor)#2 (1) {
  ["name"]=>
  string(12) "イレブン"
}
*/

printValue($team->offsetGet(0));

// 下記が出力される
/*
object(Charactor)#2 (1) {
  ["name"]=>
  string(12) "イレブン"
}
*/

以上。
お気づきの点ありましたら(温かく)ご指摘頂けると嬉しいです。