67

I'm using PHP. I have an array of objects, and would like to add an object to the end of it.

$myArray[] = null; //adds an element
$myArray[count($myArray) - 1]->name = "my name"; //modifies the element I just added

The above is functional, but is there a cleaner and more-readable way to write that? Maybe one line?

adamdport
  • 11,687
  • 14
  • 69
  • 91

4 Answers4

131

Just do:

$object = new stdClass();
$object->name = "My name";
$myArray[] = $object;

You need to create the object first (the new line) and then push it onto the end of the array (the [] line).

You can also do this:

$myArray[] = (object) ['name' => 'My name'];

However I would argue that's not as readable, even if it is more succinct.

halfer
  • 19,824
  • 17
  • 99
  • 186
  • +1 for being more readable, but it's now THREE lines. I can't create the object within a declaration? – adamdport Jan 28 '13 at 22:37
  • 2
    I think @nickb is right, you can create objects implictly, but I don't recommend it as it will probably raise a warning when you do. – halfer Jan 28 '13 at 22:38
  • 1
    I think you can cast to `(object)` to PHP, even if the intent of the code is less clear. See my answer edit. – halfer Jan 28 '13 at 22:41
  • 1
    @adamdport It depends on the definition of your class. If it takes a name in its constructor, you could do: `$myArray[] = new MyClass("My name");` But some objects won't be able to have all data set in the constructor. Then it's easier to create the object, set the parameters and then add it. – Erk Mar 22 '17 at 21:04
39

Here is a clean method I've discovered:

$myArray = [];

array_push($myArray, (object)[
        'key1' => 'someValue',
        'key2' => 'someValue2',
        'key3' => 'someValue3',
]);

return $myArray;
ahinkle
  • 2,117
  • 3
  • 29
  • 58
8

Do you really need an object? What about:

$myArray[] = array("name" => "my name");

Just use a two-dimensional array.

Output (var_dump):

array(1) {
  [0]=>
  array(1) {
    ["name"]=>
    string(7) "my name"
  }
}

You could access your last entry like this:

echo $myArray[count($myArray) - 1]["name"];
halfer
  • 19,824
  • 17
  • 99
  • 186
Frederik Kammer
  • 3,117
  • 3
  • 28
  • 29
4

Something like:

class TestClass {
private $var1;
private $var2;

private function TestClass($var1, $var2){
    $this->var1 = $var1;
    $this->var2 = $var2;
}

public static function create($var1, $var2){
    if (is_numeric($var1)){
        return new TestClass($var1, $var2);
    }
    else return NULL;
}
}

$myArray = array();
$myArray[] = TestClass::create(15, "asdf");
$myArray[] = TestClass::create(20, "asdfa");
$myArray[] = TestClass::create("a", "abcd");

print_r($myArray);

$myArray = array_filter($myArray, function($e){ return !is_null($e);});

print_r($myArray);

I think that there are situations where this constructions are preferable to arrays. You can move all the checking logic to the class.

Here, before the call to array_filter $myArray has 3 elements. Two correct objects and a NULL. After the call, only the 2 correct elements persist.

  • I recommend reading up on constructors (`function __construct`). They are PHPs built in way of doing what you're doing in your example! – Erk Mar 22 '17 at 21:06
  • 1
    @Erk: the method `private function TestClass` does the same thing, it's the old way in PHP of setting up a constructor (from PHP 4). From PHP 5, your way is preferred. – halfer Jun 30 '17 at 07:35
  • @halfer, I had a period this spring when I thought I understood PHP. I have since then realized I do not :D – Erk Aug 30 '17 at 12:38
  • @Erk: it is a never-ending journey, with any language `:-)`. – halfer Aug 30 '17 at 12:42
  • @halfer, you're right, of course, but PHP is the first language I've come a cross that IS and IS NOT at the same time. I crashed and burned on pointers that PHP HAS and HAS NOT, so now I'm running back to C# and Java :) – Erk Aug 30 '17 at 13:08