-2

I query a series of tables in order to print these, and I want to print all keys of each table even if the values are empty, but a specific set of keys which are the same for each table shall not be printed.

My query and fetch of the result in an array for one table:

$stmt = $db_conn->prepare("SELECT * FROM table;");
$stmt->execute();
$array = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();

var_export($array);returns:

array ( 0 => array ( 'a' => '1', 'b' => '2018-12-21', 'c' => '', 'd' => '', ), )

I prepared a list of bad keys in an array:

var_export($bad_keys);returns:

array ( 0 => array ( 'a' => '1', 'b' => '2019-01-05', ), )

For each table I want to exclude the bad keys {a, b} from the query result in $array by use of array_diff_key():

$array_new = array_diff_key($array, $bad_keys); 

var_dump($array_new); returns empty:

array(0) { }.

$array_new should have the keys {'c', 'd'} but it has not. I don't see a mistake in my code. Please help.

Mich
  • 19
  • 6
  • 2
    You should `var_export` arrays to get more people reproducing your code. If there is no easy copy'n'paste code, I do not even read much of the question. – Pinke Helga Jan 05 '19 at 21:37
  • Sorry I bothered you. I am a beginner. I put my bad keys into a table in the database and queried. `var_export($bad_keys)` returns: `array ( 0 => array ( 'a' => '1', 'b' => '2019-01-05 22:07:18.360', ), )`. The array now contains keys and values. Compared with the second array by array_diff_key returns a new array with non-empty result, but the keys are not filtered out. – Mich Jan 05 '19 at 22:35
  • You need a `foreach` to process each rows stored in your result table array. – Pinke Helga Jan 05 '19 at 22:40
  • My script queries each table in a loop by `for()`, and in the loop tries to filter the bad keys by `array_diff_key()`. Without success. – Mich Jan 05 '19 at 23:00
  • I delete your comment in the summary. It does not help but even contradicts my complement. – Mich Jan 06 '19 at 00:56
  • There is no `for` in your snippets. Each edit contradicts the former. You fetch a complete table using `PDOStatement::fetchAll`. Btw. `fetchAll` only makes sense in very few cases, can lead to heavy resource loads and is considered as bad practice. There is no obvious reason to call `PDOStatement::closeCursor` in the given snippets since there do not remain unfetched rows. – Pinke Helga Jan 06 '19 at 10:04
  • Please read [ask] and [mcve] – Pinke Helga Jan 06 '19 at 10:10

2 Answers2

4

array_diff_key is used to compute the difference between the keys of two or more arrays, i.e. a new array with all key/value pairs of the first array argument having keys not existing in any other array argument's keys are returned.

In your code, you try to compare the keys of your first array with an array of values (i.e. your $bad_keys, actually having numbered indexes), not the keys of the $bad_keys array. This is not how array_diff_key works.

Be sure to check out the reference at: http://php.net/manual/en/function.array-diff-key.php

One method giving you only the keys you are looking for as an array:
Just create a new array of the keys of the first array as values and then use array_diff to compare it with your $bad_keys.

To get the key/value pairs you can use this one (as Quasimodo's Clone suggested):

array_diff_key($array, array_flip($bad_keys))

UPDATE: The keys in the first array are also not at the same level as the keys in the $bad_array.

Pinke Helga
  • 6,378
  • 2
  • 22
  • 42
  • I reassured myself in the manual before posting. That's what I intended: comparing only the keys of two arrays. The string representation is the same in both arrays, so I do not understand why I can't compare an array that has values with an array that has not. – Mich Jan 05 '19 at 21:49
  • Hey Mich, the `$bad_keys` array does not contain any keys–it only has values–hence it can only return an empty array. – Dr. Kevin Wang Jan 05 '19 at 21:52
  • 1
    Your answer explains why the code does not work. Not the "difference between the keys" but the key/value pairs *of the first array argument* having keys not existing in any other array argument are returned. A more directive solution is `array_diff_key($array, array_flip($bad_keys));` This already good answer could be improved by that. – Pinke Helga Jan 05 '19 at 22:08
  • I put my bad keys into a table in the database and queried. In result I see the difference to my earlier array of values, and understand your comment. This is my new array of bad keys: array(1) { [0]=> array(2) { ["a"]=> string(1) "1" ["b"]=> string(23) "2019-01-05 22:07:18.360" } }. When comparing with my second array by array_diff_key I still get an empty array. Can you give any more hint, Kevin? – Mich Jan 05 '19 at 22:13
  • @Quasimodo I tried `array_diff_key($array, array_flip($bad_keys));`. `var_dump();` the array returned a result, but `array_diff_key()` does not filter the bad keys from the second array. – Mich Jan 05 '19 at 22:22
  • Oh, took me a while. Just realized your fetchAll returned everything wrapped inside an array. How did you init your new bad_keys? I think the key comparisons might need to occur at the same level. Essentially your fetchAll returned something like this: `array( array( "a"=>blabla, "b" => blabla,... ) )`, but your bad_array has something like this: `array("a"=>blabla, "b"=blabla)` – Dr. Kevin Wang Jan 05 '19 at 22:24
  • @Dr.KevinWang Thus I recommended: **add a copy'n'pastable** `var_export` to your question. It's no fun to read and code from an unformatted dump. – Pinke Helga Jan 05 '19 at 22:33
  • @Kevin I do not understand "How did you init your new bad keys". I complemented my summary above and added a `var_export()` of the bad keys. – Mich Jan 05 '19 at 22:42
  • Sorry, I was just trying to see how you defined the bad keys. Just do another var_export on your $bad_keys and you will see what I meant by "key comparisons might need to occur at the same level" – Dr. Kevin Wang Jan 05 '19 at 22:45
  • @Dr.KevinWang Sorry this was accidentially addressed to you by automatic completion, I wanted Mich to add an export to his question. He already has done now (I've formatted it more readable). :) – Pinke Helga Jan 05 '19 at 23:00
0

My mistake: In array_diff_key() I compared two multidimensional arrays without writing the index [0] for each array to be compared.

Solution: I added the index [0] to each array to be compared, and additionally I created an array from the result of array_diff_key()

$array = array( 0 => 
     array( 
        'a' => '', 
        'b' => '', 
        'c' => '', 
        'd' => '', 
    ), 
);

$bad_keys = array( 0 => 
     array( 
        'a' => '', 
        'b' => '', 
    ), 
);

$array_new = array( array_diff_key( $array[0], $bad_keys[0] ));

var_export( $array_new );

now returns the desired result:

array( 0 => 
     array( 
        'c' => '', 
        'd' => '', 
    ), 
);
Mich
  • 19
  • 6