• 0

Breaking my head on a multi-dimensional array


Question

Hi people! I've been trying to get a receipt # from a database and building up an array with it.

I've modified the code, at least 5 times to make it work, but I need a last push, and I can't seem to get it:


private function array_key_exists_r($needle, $haystack)
{
$result = array_key_exists($needle, $haystack);
if ($result) return $result;
foreach ($haystack as $v) {
if (is_array($v)) {
$result = $this->array_key_exists_r($needle, $v);
}
if ($result) return $result;
}
return $result;
}


while($row = $this->stmt->fetch())
{

$factura = $row['factura']; /*This is how I get the receipt's number*/
print($factura);
$result = $this->array_key_exists_r($factura,$this->factura);
if(!$result)
{
if(!in_array($factura,$this->trigger)) $this->trigger[] = $factura;
$this->factura = array($factura => array('producto_id' => array($row['producto_id']),
'producto' => array($row['producto']),
'cantidad' => array($row['cantidad']),
'price_i' => array($row['price_i']),
'tax' => array($row['tax'])
)
);

}

else
{

$this->factura[$factura]['producto_id'][] =$row['producto_id'];
$this->factura[$factura]['producto'][] =$row['producto'];
$this->factura[$factura]['cantidad'][]= $row['cantidad'];
$this->factura[$factura]['price_i'][] =$row['price_i'];
$this->factura[$factura]['tax'][] = $row['tax'];
}

}
[/CODE]

Explaining:

The code is trying to do the following:

Create an array which first keys are the receipt number, and to that receipt number add all the products that were fetched from the database.

What I'm getting:

The array is being currently overwrote by the last receipt #. I know that the root of all this evil is this portion of the code:

[CODE]
if(!in_array($factura,$this->trigger)) $this->trigger[] = $factura;
[b] $this->factura = [/b]array($factura => array('producto_id' => array($row['producto_id']),
'producto' => array($row['producto']),
'cantidad' => array($row['cantidad']),
'price_i' => array($row['price_i']),
'tax' => array($row['tax'])
)
);

[/CODE]

The bold part should actually be:

[CODE]
$this->factura[] =
[/CODE]

But by doing so, the whole schema breaks, and the receipts are not appended in order.

Now, in English:

The result I'm getting without any mods:

[CODE]
Array
(
[4] => Array
(
[producto_id] => Array
(
[0] => E5030
[1] => E5060
[2] => E0094
[3] => E7485
)

[producto] => Array
(
[0] => Product # 1
[1] => Product # 2
[2] => Product # 3
[3] => Product # 4
)

[cantidad] => Array
(
[0] => 1
[1] => 1
[2] => 1
[3] => 1
)

[price_i] => Array
(
[0] => 286.62
[1] => 301.92
[2] => 153
[3] => 481
)

[tax] => Array
(
[0] => 1
[1] => 1
[2] => 1
[3] => 1
)

)

)

[/CODE]

WHICH IS GOOD, but the other receipts are overwritten.

But if I made the change I was talking about before, I'd get:

[CODE]
Array
(
[0] => Array
(
[1] => Array
(
[producto_id] => Array
(
[0] => A4318
)

[producto] => Array
(
[0] => Product name
)

[cantidad] => Array
(
[0] => 1
)

[price_i] => Array
(
[0] => 771.12
)

[tax] => Array
(
[0] => 0
)

)

)

[1] => Array
(
[producto_id] => Array
(
[0] => 102992
)

[producto] => Array
(
[0] =>Product name
)

[cantidad] => Array
(
[0] => 1
)

[price_i] => Array
(
[0] => 1128.12
)

[tax] => Array
(
[0] => 0
)

)

[2] => Array
(
[2] => Array
(
[producto_id] => Array
(
[0] => A5816
)

[producto] => Array
(
[0] => Product name
)

[cantidad] => Array
(
[0] => 1
)

[price_i] => Array
(
[0] => 630.36
)

[tax] => Array
(
[0] => 0
)

)

)

[3] => Array
(
[4] => Array
(
[producto_id] => Array
(
[0] => E5030
)

[producto] => Array
(
[0] => Product name
)

[cantidad] => Array
(
[0] => 1
)

[price_i] => Array
(
[0] => 286.62
)

[tax] => Array
(
[0] => 1
)

)

)

[4] => Array
(
[producto_id] => Array
(
[0] => E5060
[1] => E0094
[2] => E7485
)

[producto] => Array
(
[0] => Product name
[1] => Product name
[2] => Product name
)

[cantidad] => Array
(
[0] => 1
[1] => 1
[2] => 1
)

[price_i] => Array
(
[0] => 301.92
[1] => 153
[2] => 481
)

[tax] => Array
(
[0] => 1
[1] => 1
[2] => 1
)

)

)
Array

[/CODE]

What I'm really after:

[CODE]
Array
(
[1] => Array
(
[producto_id] => Array
(
[0] => E5030

)

[producto] => Array
(
[0] => Product # 1

)

[cantidad] => Array
(
[0] => 1

)

[price_i] => Array
(
[0] => 286.62

)

[tax] => Array
(
[0] => 1

)

)

)

Array
(
[2] => Array
(
[producto_id] => Array
(
[0] => E5030
[1] => E5060
)

[producto] => Array
(
[0] => Product # 1
[1] => Product # 2
)

[cantidad] => Array
(
[0] => 1
[1] => 1
)

[price_i] => Array
(
[0] => 286.62
[1] => 301.92
)

[tax] => Array
(
[0] => 1
[1] => 1
)

)

)

Array
(
[4] => Array
(
[producto_id] => Array
(
[0] => E5030
[1] => E5060
[2] => E0094
[3] => E7485
)

[producto] => Array
(
[0] => Product # 1
[1] => Product # 2
[2] => Product # 3
[3] => Product # 4
)

[cantidad] => Array
(
[0] => 1
[1] => 1
[2] => 1
[3] => 1
)

[price_i] => Array
(
[0] => 286.62
[1] => 301.92
[2] => 153
[3] => 481
)

[tax] => Array
(
[0] => 1
[1] => 1
[2] => 1
[3] => 1
)

)

)
[/CODE]

**Note that the 3 is missing on purpose because the receipt's number does not belong to the user I'm currently fetching on the database.

I know this post is looooooooooooooooooooooooooooooooooooong, but if someone could give me a little help I'd appreciate it a lot! Thanks :D

2 answers to this question

Recommended Posts

  • 0

The array is being currently overwrote by the last receipt #. I know that the root of all this evil is this portion of the code:

>
if(!in_array($factura,$this->trigger)) $this->trigger[] = $factura;
[b] $this->factura = [/b]array($factura => array('producto_id' => array($row['producto_id']),
'producto' => array($row['producto']),
'cantidad' => array($row['cantidad']),
'price_i' => array($row['price_i']),
'tax' => array($row['tax'])
)
);

[/CODE]

The bold part should actually be:
[CODE]
$this->factura[] =
[/CODE]

But by doing so, the whole schema breaks, and the receipts are not appended in order.

Its broken (with the above fix implemented) primarily because of your array_key_exists_r() function. I'm assuming that you do understand what that function does... When processing a new row from the database, you're scanning recursively through all nested arrays within $this->factura looking for [b][u]any[/u][/b] existence of a key with a value matching the receipt number! I.e. it's checking for the existence of the receipt number amongst all existing receipt number keys, and all item number keys!!
Let me walk you through the incorrect output you printed having made your suggested fix (from the perspective of processing each row in the result set returned by the database):</pre>
<ul>Row#1: The array is empty, so array_key_exists_r() returns false and the if statement passes. You therefore create a new array containing the receipt number, and the details of the first item, which is stored in a new array entry in the format of $this-&gt;factura[0][1][itemdata], where key [0] was automatically created and [1] is the receipt number.
Row#2: A second item for receipt 1 is being processed. array_key_exists_r() finds an existing array key with a value of 1, so attempts to add the new item data to the receipt, but the receipt is at $this-factura[0][1] not $this-&gt;factura[1], so inadvertently makes a new top level array entry.
Row#3: We are now processing the first item of receipt 2. There is no array entry anywhere in $this-&gt;factura, so array_key_exists_r() returns false, and as with row #1, a new array entry is to be created. The next numerical array key is [2], which coincidentally happens to be the same as the receipt number. We end up creating $this-&gt;factura[2][2][itemdata], with the first [2] being automatically created and the second representing the receipt number.
Row#4: We are now processing receipt 4. An array key with value 4 does not exist anywhere in $this-&gt;factura (as a key representing a receipt number, and item number, or anything else), so same situation as the previous row, we create the new entry $this-&gt;factura[3][4][itemdata].
Row#5: Still on receipt 4, an array key with value 4 does now exist, so we therefore do an update as with row #2. But similarly, since receipt 4 is at $this-&gt;factura[3][4] not $this-&gt;factura[4] we inadvertently create $this-&gt;factura[4].
</ul>
<p></p>
<p>Now, try this:</p>
<div>[code]while($row = $this-&gt;stmt-&gt;fetch())
{
	$factura = $row['factura']; /*Receipt number*/
	print($factura);
	if(! array_key_exists($factura, $this-&gt;factura))
	{
		if(! in_array($factura, $this-&gt;trigger)) $this-&gt;trigger[] = $factura;
		$this-&gt;factura[$factura] = array(
			'producto_id' =&gt; array($row['producto_id']),
			'producto' =&gt; array($row['producto']),
			'cantidad' =&gt; array($row['cantidad']),
			'price_i' =&gt; array($row['price_i']),
			'tax' =&gt; array($row['tax'])
		);
	}
	else
	{
		$this-&gt;factura[$factura]['producto_id'][] =$row['producto_id'];
		$this-&gt;factura[$factura]['producto'][] =$row['producto'];
		$this-&gt;factura[$factura]['cantidad'][]= $row['cantidad'];
		$this-&gt;factura[$factura]['price_i'][] =$row['price_i'];
		$this-&gt;factura[$factura]['tax'][] = $row['tax'];
	}
}<

  • 0

Its broken (with the above fix implemented) primarily because of your array_key_exists_r() function. I'm assuming that you do understand what that function does... When processing a new row from the database, you're scanning recursively through all nested arrays within $this->factura looking for any existence of a key with a value matching the receipt number! I.e. it's checking for the existence of the receipt number amongst all existing receipt number keys, and all item number keys!!

First of all, thank you... thank you thank you...! It did the trick!!!!!!!!! :D :D :D :D:D

Before using the array_keys_r function, which I got from stackoverflow, I was using array_key_exists to verify the array, but it wasn't working as I wanted since the last receipt overwrote the previous one. I thought it was a multi-dimensional array problem so I looked up on Google and thought using that custom function. In the end it yielded the previous results I was having!

But clearly, the main problem was this little row:

$this-&gt;factura = array($factura =&gt; array('producto_id' =&gt; array($row['producto_id']),

Which you change to:

$this->factura[$factura] = array(

And through the explanation it does make a lot of sense...

I'm kind of slapping my face right now...

Really, really, really, thanks a million!

(Y)

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • Just pull a 4Chan and ignore the UK gov, or better troll them. It's not like they can enforce the fine across border.
    • It has NEVER been shown that all these overreaching creepy methods of surveillance have ever saved a child or prevented a terrorist attack. Not a single one. It's the kind of people like you who just wave it away as "paranoid conspiracy" that makes big tech and governments this creepy mass data hoarding entities. Not only that, 3/4 of these surveillance ideas undermine the very foundations of safe online communication because they always want to have a backdoor in everything "just in case" they might need it to... checks the notes "save the children". If you put a backdoor into encryption chain there is no encryption chain anymore. You know what encryption keeps safe? Your medical records, your online shopping and credit card during payment, your photos in the cloud, your emails, your passwords, everything. There is ZERO guarantee only the good guys will use it. And if you think police suddenly can't apprehend child abusers because of encryption, Epstein was running his entire sex trafficking ring using GMail which is not even encrypted end to end. Or to make matters even worse, USA has a **** and a good buddy of Epstein as a president. Absolutely NOTHING has been done to address it. Maxwell just got a better "hotel" room as a reward. This clearly shows how they absolutely don't really care about the children but they care about the absolute control over all of us. And you're defending them here. Good grief. On top of constant attempts to insert backdoors into encryption chain, the entire age verification nonsense is again entirely over reaching, creepy, invades everyone's privacy with premise of yet again "protecting the children" instead of demanding device makers to provide simple and powerful tools for PARENTS to control how their children use devices and what they do on them. THIS would be the way, not the stupid age verification for everyone. Imagine if government would be dictating companies how their phones work and not the company's IT department. The parents should be the IT department to their children. And for everyone excusing "they are not knowledgeable enough" buuuuuulsheat. We live in a digital age, if you have children now, you absolutely are well versed in digital everything at least to basic extent. If you're not, how do you even function in these times then? Reality is that parents are just lazy and don't want to deal with this. They want government to raise their kids because they are too busy scrolling stupid Instagram and Tiktok or some bs.
    • You could make the argument that K should not be included, but FC, the fried chicken, is not the framework, it's the product. It's the Paint in Paint.NET. A closer analogy is if KFC included the name of the deep fryer they used. HennyPennyFC.
    • Flying as the central point eh... As a massive Spyro fan who has replayed the Reignited Trilogy three times and the originals 4 times... I have some doubts, but maybe...
    • Apple is expanding Private Cloud Compute beyond its own data centers by Pradeep Viswanathan At WWDC 2026, as part of the improved Apple Intelligence capabilities, Apple today announced that it is expanding Private Cloud Compute (PCC), its privacy-focused cloud infrastructure for Apple Intelligence, beyond its own data centers for the first time. Private Cloud Compute was designed to handle Apple Intelligence requests that are too complex to run fully on-device. The PCC system does not store user data and does not allow Apple or anyone else to access user requests. Last year, Apple also expanded its Security Bounty program with rewards of up to $1 million for researchers who could find serious vulnerabilities in PCC. Until now, Apple's PCC data centers were using Apple's own silicon. As part of the expansion, Apple is working with Google and NVIDIA to run new Apple Intelligence workloads on Google Cloud systems powered by NVIDIA GPUs. Apple will be using this new infrastructure to execute more demanding AI tasks while maintaining the same privacy and security guarantees of PCC. The new implementation uses NVIDIA Confidential Computing with NVIDIA GPUs, Intel CPUs with TDX, and Google’s Titan chip. Apple says it has worked with Google to build additional protections beyond a traditional confidential computing deployment. Despite the expansion to third-party data centers, Apple claims that its core PCC requirements remain unchanged, including stateless computation, no privileged runtime access, non-targetability, and verifiable transparency. The company highlighted that it will continue to control the PCC software stack, and Apple devices will only trust PCC software that has been cryptographically approved by Apple. To take security to the next level, Apple mentioned that it is maintaining an append-only ledger of Google Cloud hardware that is part of the PCC fleet. The company claims this will help reduce the risk of supply chain attacks. In addition to AI infrastructure, Apple also worked with Google to use technologies behind the Gemini family of models to build the next generation of Apple Foundation Models to power Apple Intelligence features across on-device and cloud workloads. As expected, for more demanding AI tasks like agentic tool use and complex reasoning, Apple will rely on the expanded PCC infrastructure running on Google Cloud. The expansion of PCC on Google Cloud will gradually ramp toward the full set of protections during the summer preview period. As before, Apple will also publish binaries for public inspection, provide research tooling, and give researchers access to live PCC nodes in research mode through the Apple Security Bounty Program.
  • Recent Achievements

    • Very Popular
      Captain_Eric earned a badge
      Very Popular
    • One Month Later
      amusc earned a badge
      One Month Later
    • One Month Later
      DJC50PLUS earned a badge
      One Month Later
    • Week One Done
      DJC50PLUS earned a badge
      Week One Done
    • Proficient
      Eric Biran went up a rank
      Proficient
  • Popular Contributors

    1. 1
      +primortal
      506
    2. 2
      PsYcHoKiLLa
      222
    3. 3
      ATLien_0
      92
    4. 4
      +Edouard
      86
    5. 5
      Steven P.
      81
  • Tell a friend

    Love Neowin? Tell a friend!