2010-04-26 8 views
24

Question simple, comment convertir un tableau associatif en variables dans une classe? Je sais qu'il y a du casting pour faire un (object) $myarray ou quoi que ce soit, mais cela va créer un nouveau stdClass et ne m'aide pas beaucoup. Existe-t-il des méthodes simples à une ou deux lignes pour transformer chaque paire $key => $value de ma matrice en une variable $key = $value pour ma classe? Je ne trouve pas cela très logique d'utiliser une boucle foreach pour cela, je ferais mieux de simplement le convertir en stdClass et de le stocker dans une variable, n'est-ce pas?Conversion d'un tableau PHP en variables de classe

class MyClass { 
    var $myvar; // I want variables like this, so they can be references as $this->myvar 
    function __construct($myarray) { 
     // a function to put my array into variables 
    } 
} 

Répondre

59

Ce code simple devrait fonctionner:

<?php 

    class MyClass { 
    public function __construct(Array $properties=array()){ 
     foreach($properties as $key => $value){ 
     $this->{$key} = $value; 
     } 
    } 
    } 

?> 

Exemple d'utilisation

$foo = new MyClass(array("hello" => "world")); 
$foo->hello // => "world" 

Sinon, cela pourrait être une meilleure approche

<?php 

    class MyClass { 

    private $_data; 

    public function __construct(Array $properties=array()){ 
     $this->_data = $properties; 
    } 

    // magic methods! 
    public function __set($property, $value){ 
     return $this->_data[$property] = $value; 
    } 

    public function __get($property){ 
     return array_key_exists($property, $this->_data) 
     ? $this->_data[$property] 
     : null 
     ; 
    } 
    } 

?> 

L'utilisation est la même

// init 
$foo = new MyClass(array("hello" => "world")); 
$foo->hello;   // => "world" 

// set: this calls __set() 
$foo->invader = "zim"; 

// get: this calls __get() 
$foo->invader;  // => "zim" 

// attempt to get a data[key] that isn't set 
$foo->invalid;  // => null 
+0

Ne pensez pas que vous avez besoin de {} dans la valeur de $ this -> {$ key} = $; déclaration – AntonioCS

+13

@AntonioCS, ce n'est pas nécessaire mais il souligne définitivement l'accès d'une propriété nommée par une variable. Cela démontre aussi que '{}' peut être utilisé quand la propriété de la variable devient plus complexe; Par exemple, '$ this -> {$ this-> foo ('bar')} -> do_something();' –

+0

Vraiment deux bonnes solutions. Je n'étais pas au courant de ces méthodes magiques, astuces soignées. – John

1

Voici une autre solution en utilisant PDOStatement::fetchObject, mais il est un peu un hack.

$array = array('property1' => 'value1', 'property2' => 'value2'); 
$className = 'MyClass'; 

$pdo = new PDO('sqlite::memory:'); // we don't actually need sqlite; any PDO connection will do 
$select = 'SELECT ? AS property1, ? AS property2'; // this could also be built from the array keys 
$statement = $pdo->prepare($select); 

// this last part can also be re-used in a loop 
$statement->execute(array_values($array)); 
$myObject = $statement->fetchObject($className); 
0

Définir une méthode statique pour convertir obtenir une instance d'un tableau. Mieux, définissez une interface pour cela. Ceci est déclaratif, ne pollue pas le constructeur, vous permet de définir des propriétés privées et d'implémenter une logique personnalisée qui ne serait pas possible avec Reflection. Si vous voulez une solution générique, définissez un trait et utilisez-le dans vos classes.

class Test implements ContructableFromArray { 
    private $property; 
    public static function fromArray(array $array) { 
     $instance = new self(); 
     $instance->property = $array['property']; 
     return $instance; 
    } 
} 

interface ConstructableFromArray { 
    public static function fromArray(array $array); 
} 
0

si vous (comme moi) venu ici à la recherche d'un générateur de code source pour array-> classe, je ne pouvais pas vraiment trouver, puis je suis venu avec ce (un travail en cours, pas bien testé ou quoi que ce soit, json_decode renvoie le tableau.):

<?php 
declare(strict_types = 1); 

$json = <<<'JSON' 
{"object_kind":"push","event_name":"push","before":"657dbca6668a99012952c58e8c8072d338b48d20","after":"5ac3eda70dbb44bfdf98a3db87515864036db0f9","ref":"refs/heads/master","checkout_sha":"5ac3eda70dbb44bfdf98a3db87515864036db0f9","message":null,"user_id":805411,"user_name":"hanshenrik","user_email":"[email protected]","user_avatar":"https://secure.gravatar.com/avatar/e3af2bd4b5604b0b661b5e6646544eba?s=80\u0026d=identicon","project_id":3498684,"project":{"name":"gitlab_integration_tests","description":"","web_url":"https://gitlab.com/divinity76/gitlab_integration_tests","avatar_url":null,"git_ssh_url":"[email protected]:divinity76/gitlab_integration_tests.git","git_http_url":"https://gitlab.com/divinity76/gitlab_integration_tests.git","namespace":"divinity76","visibility_level":0,"path_with_namespace":"divinity76/gitlab_integration_tests","default_branch":"master","homepage":"https://gitlab.com/divinity76/gitlab_integration_tests","url":"[email protected]:divinity76/gitlab_integration_tests.git","ssh_url":"[email protected]:divinity76/gitlab_integration_tests.git","http_url":"https://gitlab.com/divinity76/gitlab_integration_tests.git"},"commits":[{"id":"5ac3eda70dbb44bfdf98a3db87515864036db0f9","message":"dsf\n","timestamp":"2017-06-14T02:21:50+02:00","url":"https://gitlab.com/divinity76/gitlab_integration_tests/commit/5ac3eda70dbb44bfdf98a3db87515864036db0f9","author":{"name":"hanshenrik","email":"[email protected]"},"added":[],"modified":["gitlab_callback_page.php"],"removed":[]}],"total_commits_count":1,"repository":{"name":"gitlab_integration_tests","url":"[email protected]:divinity76/gitlab_integration_tests.git","description":"","homepage":"https://gitlab.com/divinity76/gitlab_integration_tests","git_http_url":"https://gitlab.com/divinity76/gitlab_integration_tests.git","git_ssh_url":"[email protected]:divinity76/gitlab_integration_tests.git","visibility_level":0}}   
JSON; 
$arr = json_decode ($json, true); 

var_dump (array_to_class ($arr)); 

/** 
* 
* @param array $arr    
* @param string $top_class_name    
*/ 
function array_to_class(array $arr, string $top_class_name = "TopClass"): string { 
    $top_class_name = ucfirst ($top_class_name); 
    $classes = array(); // deduplicated 'definition'=>true,array_keys(); 
    $internal = function (array $arr, string $top_class_name) use (&$classes, &$internal) { 
     $curr = 'Class ' . $top_class_name . ' {' . "\n"; 
     foreach ($arr as $key => $val) { 
      $type = gettype ($val); 
      if (is_array ($val)) { 
       $type = ucfirst ((string) $key); 
       $classes [$internal ($val, (string) $key)] = true; 
      } 
      $curr .= <<<FOO 
    /** 
    * @property $type \$$key 
    */ 
FOO; 
      $curr .= "\n public $" . $key . ";\n"; 
     } 
     $curr .= '}'; 
     $classes [$curr] = true; 
    }; 
    $internal ($arr, $top_class_name); 
    return implode ("\n", array_keys ($classes)); 
} 

sortie:

Class project { 
    /** 
    * @property string $name 
    */ 
    public $name; 
    /** 
    * @property string $description 
    */ 
    public $description; 
    /** 
    * @property string $web_url 
    */ 
    public $web_url; 
    /** 
    * @property NULL $avatar_url 
    */ 
    public $avatar_url; 
    /** 
    * @property string $git_ssh_url 
    */ 
    public $git_ssh_url; 
    /** 
    * @property string $git_http_url 
    */ 
    public $git_http_url; 
    /** 
    * @property string $namespace 
    */ 
    public $namespace; 
    /** 
    * @property integer $visibility_level 
    */ 
    public $visibility_level; 
    /** 
    * @property string $path_with_namespace 
    */ 
    public $path_with_namespace; 
    /** 
    * @property string $default_branch 
    */ 
    public $default_branch; 
    /** 
    * @property string $homepage 
    */ 
    public $homepage; 
    /** 
    * @property string $url 
    */ 
    public $url; 
    /** 
    * @property string $ssh_url 
    */ 
    public $ssh_url; 
    /** 
    * @property string $http_url 
    */ 
    public $http_url; 
} 

Class author { 
    /** 
    * @property string $name 
    */ 
    public $name; 
    /** 
    * @property string $email 
    */ 
    public $email; 
} 
Class added { 
} 
Class modified { 
    /** 
    * @property string $0 
    */ 
    public $0; 
} 
Class removed { 
} 
Class 0 { 
    /** 
    * @property string $id 
    */ 
    public $id; 
    /** 
    * @property string $message 
    */ 
    public $message; 
    /** 
    * @property string $timestamp 
    */ 
    public $timestamp; 
    /** 
    * @property string $url 
    */ 
    public $url; 
    /** 
    * @property Author $author 
    */ 
    public $author; 
    /** 
    * @property Added $added 
    */ 
    public $added; 
    /** 
    * @property Modified $modified 
    */ 
    public $modified; 
    /** 
    * @property Removed $removed 
    */ 
    public $removed; 
} 
Class commits { 
    /** 
    * @property 0 $0 
    */ 
    public $0; 
} 
Class repository { 
    /** 
    * @property string $name 
    */ 
    public $name; 
    /** 
    * @property string $url 
    */ 
    public $url; 
    /** 
    * @property string $description 
    */ 
    public $description; 
    /** 
    * @property string $homepage 
    */ 
    public $homepage; 
    /** 
    * @property string $git_http_url 
    */ 
    public $git_http_url; 
    /** 
    * @property string $git_ssh_url 
    */ 
    public $git_ssh_url; 
    /** 
    * @property integer $visibility_level 
    */ 
    public $visibility_level; 
} 
Class TopClass { 
    /** 
    * @property string $object_kind 
    */ 
    public $object_kind; 
    /** 
    * @property string $event_name 
    */ 
    public $event_name; 
    /** 
    * @property string $before 
    */ 
    public $before; 
    /** 
    * @property string $after 
    */ 
    public $after; 
    /** 
    * @property string $ref 
    */ 
    public $ref; 
    /** 
    * @property string $checkout_sha 
    */ 
    public $checkout_sha; 
    /** 
    * @property NULL $message 
    */ 
    public $message; 
    /** 
    * @property integer $user_id 
    */ 
    public $user_id; 
    /** 
    * @property string $user_name 
    */ 
    public $user_name; 
    /** 
    * @property string $user_email 
    */ 
    public $user_email; 
    /** 
    * @property string $user_avatar 
    */ 
    public $user_avatar; 
    /** 
    * @property integer $project_id 
    */ 
    public $project_id; 
    /** 
    * @property Project $project 
    */ 
    public $project; 
    /** 
    * @property Commits $commits 
    */ 
    public $commits; 
    /** 
    * @property integer $total_commits_count 
    */ 
    public $total_commits_count; 
    /** 
    * @property Repository $repository 
    */ 
    public $repository; 
} 
0

Si vous voulez lancer tableau imbriqué pour objet l'utilisation de ce code:

class ToObject 
{ 
    private $_data; 

    public function __construct(array $data) 
    { 
     $this->setData($data); 
    } 

    /** 
    * @return array 
    */ 
    public function getData() 
    { 
     return $this->_data; 
    } 

    /** 
    * @param array $data 
    */ 
    public function setData(array $data) 
    { 
     $this->_data = $data; 
     return $this; 
    } 

    public function __call($property, $args) 
    { 
     // NOTE: change lcfirst if you need (ucfirst/...) or put all together 
     $property = lcfirst(str_replace('get', '', $property)); 
     if (array_key_exists($property, $this->_data)) { 
      if (is_array($this->_data[$property])) { 
       return new self($this->_data[$property]); 
      } 
      return $this->_data[$property]; 
     } 
     return null; 
    } 
} 

Ensuite, vous pouvez utiliser comme ceci:

$array = [ 
    'first' => '1.1', 
    'second' => [ 
     'first' => '2.1', 
     'second' => '2.2', 
     'third' => [ 
      'first' => '2.3.1' 
     ] 
    ] 
]; 
$object = new ToObject($array); 
$object->getFirst(); // returns 1.1 
$object->getSecond()->getFirst(); // returns 2.1 
$object->getSecond()->getData(); // returns second array 
$object->getSecond()->getThird()->getFirst(); // returns 2.3.1 
0

La meilleure solution est d'avoir trait avec la fonction statique fromArray qui peut être utilisé pour le chargement de données:

trait FromArray { 
public static function fromArray(array $data = []) { 
    foreach (get_object_vars($obj = new self) as $property => $default) { 
    if (!array_key_exists($property, $data)) continue; 
    $obj->{$property} = $data[$property]; // assign value to object 
    } 
    return $obj; 
    } 
} 

vous pouvez utiliser ce trait comme ça:

class Example { 
    use FromArray; 
    public $data; 
    public $prop; 
} 

Ensuite, vous pouvez appeler la fonction statique fromArray pour obtenir nouvelle instance de l'exemple classe:

$obj = Example::fromArray(['data' => 123, 'prop' => false]); 
var_dump($obj); 

J'ai aussi la version beaucoup plus sophistiquée avec le filtrage d'imbrication et de la valeur https://github.com/OzzyCzech/fromArray