0

I am trying to get data from mysql data, create objects from it. Here I have written some code. I am getting thing's details from a database. Now for each result I want an object to be created which is finally merged with an array output. This $output array is finally outputted as json.

I am getting error :

array_merge(): Argument #2 is not an array

How to create arrays of objects in PHP ?

public function getDetails()    //This is a class function
{
    $query = "SELECT * FROM `thing` WHERE `id` = :thingId";
    $stmt = $dbh->prepare ( $query );
    $stmt->bindParam ( ":thingId" , $_GET['thingId']  );
    $stmt->execute ( );
    $rslt  =  $stmt->fetch ( );
    $thingName  = $rslt['name'];
    $thingOwnerId = $rslt['userId'];
    $thingDescription = $rslt['thingDescription'];

    // Getting the thing owner details
    $query = "SELECT * from `user` WHERE ( `id` = :id ) ";    
    $stmt = $dbh->prepare( $query );
    $stmt->bindParam ( ":id" , $thingOwnerId );
    $stmt->execute(  );
    $rslt = $stmt->fetch ( );
    $thingOwnerName = $rslt['firstName']." ".$rslt['lastName'];
}

$query = "SELECT * FROM `things` ; ";
$s = $dbh->prepare($query);
$s->execute();
$r = $s->fetchAll();
foreach($r as $r1)
{
    $newThing = new Thingy($r1['id']);
    $newThing->getDetails();
    $output =  array_merge($output,$newThing);
}

$output2 = json_encode($output);
header('content-type: application/json');
echo $output2;
2
  • 2
    And where you've defined your parameter#2 i.e. $newRoute ? Commented Nov 8, 2013 at 12:40
  • You have not defined variable $newRoute so it value is undefined and array_merge requires arguments as array so php fires error. Commented Nov 8, 2013 at 12:41

3 Answers 3

1

You could do the following:

$output = [];
foreach($r as $r1)
{
    $newThing = new Thingy($r1['id']);
    $newThing->getDetails();
    $output[] = $newThing;
}
Sign up to request clarification or add additional context in comments.

Comments

1

You could save yourself some work here and use PDO::FETCH_CLASS as the $fetch_style. Basically it allows you to specify a custom class, the properties of which you can populate with matching return values from each row in your query. Note the first argument in the method signature:

public array PDOStatement::fetchAll ([ int $fetch_style [, mixed $fetch_argument [, array $ctor_args = array() ]]] )

As illustrated in example #4 from the PDOStatement::fetchAll() documentation

<?php
class fruit {
    public $name;
    public $colour;
}

$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();

$result = $sth->fetchAll(PDO::FETCH_CLASS, "fruit");
var_dump($result);

Hope this helps :)

2 Comments

Thanks ! Thats really helpful ! But I am getting data from multiple tables. And creating a single object out of it. Will it work in that case ?
Yes it should be completely fine, all you need is an object with the same properties as the columns you are returning from your database - this can be from one or many tables - you are mapping the returned data to the object, so PHP does not care about the underlying table structure. It's a pretty useful feature imho!
0

I see a couple things that could potentially be causing problems.

First, and likely the cause of your issues, is that array_merge only accepts arguments of type array. See the documentation. However, you can either cast the type of $newThing to be an array, or more succinctly just do a manual append as suggested in this other answer.

Second, your method getDetails() neither returns anything, nor does is it a class method that modifies an object's contents. It needs to be one or the other; right now it runs and the results aren't permanently stored anywhere. Since you've indicated it's a class method, then it should look like this:

public function getDetails()    //This is a class function
{
    $query = "SELECT * FROM `thing` WHERE `id` = :thingId";
    $stmt = $dbh->prepare ( $query );
    $stmt->bindParam ( ":thingId" , $_GET['thingId']  );
    $stmt->execute ( );
    $rslt  =  $stmt->fetch ( );
    $this->thingName  = $rslt['name'];                    // Class variable
    $this->thingOwnerId = $rslt['userId'];                // Class variable
    $this->thingDescription = $rslt['thingDescription'];  // Class variable

    // Getting the thing owner details
    $query = "SELECT * from `user` WHERE ( `id` = :id ) ";    
    $stmt = $dbh->prepare( $query );
    $stmt->bindParam ( ":id" , $thingOwnerId );
    $stmt->execute(  );
    $rslt = $stmt->fetch ( );
    $this->thingOwnerName = $rslt['firstName']." ".$rslt['lastName']; // Class variable
}

2 Comments

Updated my question. $newRoute isn't the problem. Also, the getDetails() doesn't returns anything but it does defines many attributes of the object created.
It's not a class method, so it's not modifying any attributes either. Unless you omitted the class definitions and use of $this-> before posting your code?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.