0

I have this array

 $products[0]['productid']   = 5;
 $products[0]['name'] = "apples";
 $products[0]['seller'] = 1;

 $products[1]['productid']   = 15;
 $products[1]['name'] = "orange";
 $products[1]['seller'] = 1;

 $products[2]['productid']   = 5;
 $products[2]['name'] = "apples";
 $products[2]['seller'] = 2;
 // .... more 5000 products

this array is filled by the client with ajax. I need to make a restriction that $products array don't have the same productid in any of it's other members. as in the invalid data example above 5

What I do to get that done is by doing this

$onlyids = array();
for($x=0; $x < count($products); $x++){
   $onlyids[]=$products[$x]['productid'];//get only productid in an array
}
//remove duplicate members
$onlyids2= array_unique($onlyids);
 //check if there were duplicates
if(count($onlyids) != count($onlyids2)){
   //same id found, reject client inputs
}

did I do it correct ? or there is a better performing way. because my way is obviously consume more time on big arrays?

Accountant م
  • 6,975
  • 3
  • 41
  • 61
  • What you have there is fine in essence - but how are you storing this array? Are you using a database? It just seems very inefficient – JBithell Oct 20 '16 at 10:52
  • check [How to remove duplicate values from a multi-dimensional array in PHP](http://stackoverflow.com/questions/307674/how-to-remove-duplicate-values-from-a-multi-dimensional-array-in-php) – jitendrapurohit Oct 20 '16 at 10:52
  • @JBithell it come from the client. if it's ok, I store it in mysql – Accountant م Oct 20 '16 at 10:57
  • @deceze has a great answer - but as an alternative you could upload each item to MySQL and then use an auto increment field for the id to be set automatically – JBithell Oct 20 '16 at 10:58
  • @JBithell I don't want to make sure that ids is different and store them all. I want to reject the inputs that has the same product and inform the user that data is invalid. – Accountant م Oct 20 '16 at 11:08
  • Why not check it before adding it to the array? – RST Oct 20 '16 at 11:15
  • @RST do you mean on the client side? javascript? – Accountant م Oct 20 '16 at 11:18
  • I don't know your workflow for adding products to this array. Right now it feels like you are allowing everybody to get on board of a bus, once everyone found a seat you start checking tickets and tell people without a ticket to leave the bus. Why not check before they enter? – RST Oct 20 '16 at 11:20
  • @RST "this array is filled by the client with ajax". yes I do my "tickets checking" on the client side with javascript. but I also need to do the same check on the server side – Accountant م Oct 20 '16 at 11:26
  • Okay I misunderstood. – RST Oct 20 '16 at 11:30

1 Answers1

4

Probably the most performant way is to store found product ids as array keys while you iterate the data:

$productIds = [];

foreach ($products as $product) {
    if (isset($productIds[$product['productid']])) {
        throw new Exception('Duplicate product id ' . $product['productid']);
    }
    $productIds[$product['productid']] = true;
}

echo 'All good';

More obscure and inefficient, but a one-liner:

if (max(array_count_values(array_column($products, 'productid'))) > 1) {
    throw new Exception('Invalid input');
}
deceze
  • 510,633
  • 85
  • 743
  • 889