0

I have a SQLite3 database which contains 4 tables with 9 rows each. I've tried to do each one of the arrays one-by-one, with basically the same code as below (everything in the foreach loop), and it worked fine. I guess I just made some stupid mistakes (I don't really use PHP, this is pretty much the only project I've used it in). I tried to fix it, but somehow PHP is not really friendly today. Currently the code below returns a JSON with 4 empty arrays.

<?php 
  header('Content-type: application/json');
  $db = new PDO('sqlite:whad.db')or die('Could not open database');

$arDaniel = array();
$arAndi = array();
$arDave = array();
$arSimon = array();

for ($j=0; $j < 4; $j++) { 
  $name;
  $arr;

  if (j == 0) {
    $name = 'Daniel';
    $arr = $arDaniel;
  }
  elseif (j == 1) {
    $name = 'Andi';
    $arr = $arAndi;
  }
  elseif (j == 2) {
    $name = 'Dave';
    $arr = $arDave;
  }
  elseif (j == 3) {
    $name = 'Simon';
    $arr = $arSimon;
  }

  $query = "SELECT Datum, ID, RR, RL, KB, BD, SD, KH, Reihenfolge FROM $name ORDER BY date(Datum)";
  $i = 1;
  foreach($res = $db->query($query) as $value) {
    $curr = array();
    array_push($curr["Datum"] = $value[0]);
    array_push($curr["ID"] = $value[1]);
    array_push($curr["RR"] = $value[2]);
    array_push($curr["RL"] = $value[3]);
    array_push($curr["KB"] = $value[4]);
    array_push($curr["BD"] = $value[5]);
    array_push($curr["SD"] = $value[6]);
    array_push($curr["KH"] = $value[7]);
    array_push($curr["Reihenfolge"] = $value[8]);
    array_push($arr[$i] = $curr);
    $i++;
  }
}
$json = array(
    "Daniel" => $arDaniel,
    "Andi" => $arAndi,
    "Dave" => $arDave,
    "Simon" => $arSimon
  );

echo json_encode($json);

$db = NULL;
?>

EDIT: Removed quotes around $curr.

3
  • What is this line array_push($arr[$i] = "$curr"); really doing? Commented Feb 9, 2016 at 22:38
  • First, I put the SQLite data of a row in the array $curr. After that, I put it in one of the 4 arrays ($arDaniel, $arAndi, $arDave, $arSimon; Which are basically the tables of the database). So I return one JSON with 4 nested objects. One for each array. In each array the entries are labeled from 1-n, n being the amount of columns in the database. Commented Feb 9, 2016 at 22:42
  • Oh, but the qutes shouldn't be around $curr. Commented Feb 9, 2016 at 22:46

2 Answers 2

1

You have many unnecassary variables with the same data. You simply could do the following

<?php
header('Content-type: application/json');
$db = new PDO('sqlite:whad.db')or die('Could not open database');

$json = array(
  "Daniel" => array(),
  "Andi" => array(),
  "Dave" => array(),
  "Simon" => array()
);

foreach($json as $name => &$arr){
  $query = "SELECT Datum, ID, RR, RL, KB, BD, SD, KH, Reihenfolge FROM $name ORDER BY date(Datum)";

  $stmt = $db->query($query);
  //now comes the trick, that you tell pdo to fecth them already as array
  $arr = $stmt->fetchAll(PDO::FETCH_ASSOC);
}

unset($arr);


echo json_encode($json);
?>

Look at the first example here: http://php.net/manual/de/pdostatement.fetchall.php

Also note the & before $arr, which will handle the $arr variable as reference (also the unset, because after the last pass, it would still be set, this is just good style to clean up)

Update: As in the other answer you have to use PDO::FETCH_ASSOC to get an array with only the index names.

Sign up to request clarification or add additional context in comments.

1 Comment

I just fixed my version (forgot the "$" in the if statements), but your version is way easier on the eyes. However, when I use it, it returns all my data twice. One time numberes 1-n, and directly below (in the same JSON nest layer) with the row labels. Is it possible to only send the one with the labels?
0

There are more than one error in your code:

$arDaniel = array();
$arAndi = array();
$arDave = array();
$arSimon = array();

for ($j=0; $j < 4; $j++) { 
    $name;                                              # <---
    $arr;                                               # <---

This sort of ‘declaration’ in php is unnecessary, you can remove $name and $arr (it's not an error, btw);

    if (j == 0) {                                       # <---

In the for loop you use $j, you can't use j here: replace it with $j (in php variables are ever prepended by $);

        $name = 'Daniel';
        $arr = $arDaniel;                               # <---

By this assignment, you want change the original array, but with this assignment by value, you in fact create a copy of $arDaniel, and new elements are added only to $arr, not to $arDaniel; to do this, you have to do an assignment by reference through & keyword: replace this (and following similar) line with $arr = &$arDaniel;

    }
        elseif (j == 1) {                               # <--- see above
        $name = 'Andi';
        $arr = $arAndi;                                 # <--- see above
    }
        elseif (j == 2) {                               # <--- see above
        $name = 'Dave';
        $arr = $arDave;                                 # <--- see above
    }
        elseif (j == 3) {                               # <--- see above
        $name = 'Simon';
        $arr = $arSimon;                                # <--- see above
    }
    $query = "SELECT Datum, ID, RR, RL, KB, BD, SD, KH, Reihenfolge FROM $name ORDER BY date(Datum)";
    $i = 1;                                             # <--- 

The query is formally correct, but I don't know your table structure. $i = 1; is unnecessary (see below);

    foreach($res = $db->query($query) as $value) {
        $curr = array();
        array_push($curr["Datum"] = $value[0]);         # <---
        array_push($curr["ID"] = $value[1]);            # <---
        array_push($curr["RR"] = $value[2]);            # <---
        array_push($curr["RL"] = $value[3]);            # <---
        array_push($curr["KB"] = $value[4]);            # <---
        array_push($curr["BD"] = $value[5]);            # <---
        array_push($curr["SD"] = $value[6]);            # <---
        array_push($curr["KH"] = $value[7]);            # <---
        array_push($curr["Reihenfolge"] = $value[8]);   # <---
        array_push($arr[$i] = $curr);                   # <---
        $i++;                                           # <---
    }
}

The array_push syntax is not correct (see manual page): the correct syntax is array_push( $existentArray, $newElement ). In addition, you can't use array_push to add an associative value, you can use it only for numeric key. Change $curr assignments simply in $curr['Datum'] = $value[0]; etc...

To append $curr to $arr, you have to change the line in array_push( $arr, $curr ) or (better, as php recommends if only one element is appended) $arr[] = $curr;. After these changes, the $i++; line can be deleted.

$json = array(
    "Daniel" => $arDaniel,
    "Andi" => $arAndi,
    "Dave" => $arDave,
    "Simon" => $arSimon
);

echo json_encode($json);

$db = NULL;

Now your script is clean (I hope).

Your script remain a bit redundant. You can simplify it in this way:

$array = array( 'Daniel'=>array(), 'Andi'=>array(), 'Dave'=>array(), 'Simon'=>array() );
foreach( $array as $key => &$val )
{
    $query = "SELECT Datum, ID, RR, RL, KB, BD, SD, KH, Reihenfolge FROM $key ORDER BY date(Datum)";

    $result = $db->query( $query );
    $val    = $result->fetchAll( PDO::FETCH_ASSOC );
}

$json = json_encode( $array );
echo $json;

By this way, you init an array with names as key, then, in a foreach loop by reference (&$val) you perform a sql query searching in table $key and you fetch all results directly in array (in this example the values are stored as associative arrays, like in your example, but you can use PDO::FETCH_OBJ to store data as object). At the end, you encode the array end echo it.

Edit:

I see a previous answer nearly identical to mine... BTW, I leave mine because I have spent a lot of time to explain various errors...

1 Comment

Thank you for taking the time and explaining my errors! I had already fixed a couple of those, and it worked (well, slow, but it did), but yours and Fabian's is a lot easier to read and faster. Thank both of you!

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.