I have a database with different kind of products that have similar ID's (EAN codes). I'm trying to print a list of all similar codes so I can import them and connect them to the same product.
Example:
Product Y has ID 190198001795 and 0190198001795
Product X has ID 190198001780, 0190198001780 and 00190198001780
What I'm trying to achieve:
190198001795 - 0190198001795
190198001795 - 0190198001780 - 00190198001780
What did I try:
Create a foreach to 'group' the similar ID's, but eventually this may corrupt the correct groups.
<?
// GET ALL PRODUCT ID's
$sql = "SELECT * FROM `products`";
$result = $mysqli->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
// Total Downloads - Thousand sperator
$shopID = $row["id"];
$EAN = $row["ean"];
$sqlDouble = "SELECT * FROM `products` WHERE `EAN` IN ('$EAN','0$EAN','00$EAN','000$EAN') LIMIT 200";
$resultDouble = $mysqli->query($sqlDouble);
if ($resultDouble->num_rows > 1) {
// output data of each row
while($row = $resultDouble->fetch_assoc()) {
$EAN = $row["ean"];
$shopID = $row["id"];
$children[] = $EAN;
}
}
}
}
foreach (array_chunk($children, 2, true) as $array) {
echo '<div>';
foreach($array as $kicks) {
echo $kicks." ";
}
echo '</div>';
}
?>
Is there another way to parse trough my rows and check / combine similar ID's?
Try this. See comments for explanation. Outputs:
array(2) {
[190198001780]=>
array(2) {
[2]=>
string(13) "0190198001780"
[8]=>
string(14) "00190198001780"
}
[1234]=>
array(2) {
[5]=>
string(5) "01234"
[6]=>
string(6) "001234"
}
}
Code:
<?php
$eans = ['190198001780', '8715839583923', '0190198001780', '015839583923', '1234', '01234', '001234', '001235', '00190198001780'];
foreach ($eans as $ean)
{
// For all EANs that do not have a leading zero, try to find
// similar ones by looking for the same code with one or more leading
// zeroes.
if ($ean[0] !== '0' && ctype_digit($ean))
{
// Look for any occurrences of this EAN with one or more (+) leading zeroes.
// If no similar EANs found, then don't record any.
if ($matches = preg_grep('/[0]+' . $ean . '/', $eans))
$children[$ean] = $matches;
}
}
var_dump($children);
/*
array(2) {
[190198001780]=>
array(2) {
[2]=>
string(13) "0190198001780"
[8]=>
string(14) "00190198001780"
}
[1234]=>
array(2) {
[5]=>
string(5) "01234"
[6]=>
string(6) "001234"
}
}
*/
Related
I am currently developing a CLI using Symfony Console and I have run into a problem regarding adding a row spanning multiple rows.
My code is
$table = new Table($output);
$table->setHeaders(['Elements','Properties']);
foreach($elements as $key => $element) {
if ($key != 'templates') {
//process element
$rowcount = 0;
foreach($element as $name => $component){
if(is_string($component)){
$strings[] = $name.' = '.($component == '' ? 'empty' : $component);
$rowcount++;
}
}
//creating row
$count = 0;
foreach ($strings as $string) {
if ($count == 0) {
$frow[] = new TableCell($key, ['rowspan' => $rowcount]);
$frow[] = $string;
} else {
$row[] = $string;
}
$count++;
}
$rows = [$frow,$row];
var_dump($rows);
$table->addRows($rows);
unset($frow,$row,$strings);
}
}
$table->setStyle('borderless');
$table->render();
The var_dump at this point creates this result
array(2) {
[0]=>
array(2) {
[0]=>
object(Symfony\Component\Console\Helper\TableCell)#63 (2) {
["value":"Symfony\Component\Console\Helper\TableCell":private]=>
string(5) "forms"
["options":"Symfony\Component\Console\Helper\TableCell":private]=>
array(2) {
["rowspan"]=>
int(4)
["colspan"]=>
int(1)
}
}
[1]=>
string(12) "name = forms"
}
[1]=>
array(3) {
[0]=>
string(18) "path = admin/forms"
[1]=>
string(14) "scope = system"
[2]=>
string(16) "attachto = empty"
}
}
The CLI should appear like this
============= ===================
Elements Properties
============= ===================
forms name = forms
path = admin/forms
scope = system
attachto = empty
I don't know if this is too much but the problem is the alignment of the second column is completely disjointed.The scope=system section moves to a 3rd column.
I have seen the following: array_merge() How can I add a 'range' of an array name and the answers don't work for me.
I have an array that I am looping through in order to slice and convert certain currency strings to float numbers. I then have to array_merge them back together in order to work with the array and have been dynamically naming them so that I don't overwrite the previous array_merge. After doing so, I then need to combine all of the dynamically named arrays into one array.
Initially I had the following code, which worked great when I only had 3 nested arrays in the $order['product'] array. However, this number varies, and the code needs to do so as well.
$nr = 1;
foreach ($order['product'] as $product) {
$product_total = array_slice($product, 1);
array_walk($product_total, "convertCurrencyStringtoNumber");
${"final_product" . $nr} = array_merge($product, $product_total);
$nr++;
};
$arrays = array($final_product1, $final_product2, $final_product3);
var_dump($arrays);
This results in the following array:
array(3) {
[0]=> array(2) {
["source_code"]=> string(10) "408000-025"
["total"]=> float(18) }
[1]=> array(2) {
["source_code"]=> string(10) "408000-025"
["total"]=> float(17) }
[2]=> array(2) {
["source_code"]=> string(10) "408000-025"
["total"]=> float(2.75) } }
How do I implement a varied number of dynamically named arrays in the line:
$arrays = array($final_product1, $final_product2, $final_product3);
I attempted the following, but the array is nested incorrectly. Feel free to fix this code or come up with a better solution.
$nr = 1;
$i = 1;
foreach ($order['product'] as $product) {
$product_total = array_slice($product, 1);
array_walk($product_total, "convertCurrencyStringtoNumber");
${"final_product" . $nr} = array_merge($product, $product_total);
if ($nr > 0) {
$arrays = $final_product1;
for ($i = 2; $i <= $nr; $i++) {
$arrays = array_merge($arrays, ${"final_product" . $nr});
}
} else {
echo "There are no products in this order";
}
$nr++;
};
var_dump($arrays);
This results in the incorrectly nested array:
array(2) {
[0]=> array(2) {
[0]=> array(2) {
["source_code"]=> string(10) "408000-025"
["total"]=> float(18) }
[1]=> array(2) {
["source_code"]=> string(10) "408000-025"
["total"]=> float(17) } }
[1]=> array(2) {
["source_code"]=> string(10) "408000-025"
["total"]=> float(2.75) } }
Simply replace your dynamically single-named variables with an array:
$final_product = array();
foreach ($order['product'] as $product) {
$product_total = array_slice($product, 1);
array_walk($product_total, "convertCurrencyStringtoNumber");
$final_product[] = array_merge($product, $product_total);
};
var_dump($final_product);
Unless I'm missing something here... this should be as easy and simple as:
$final_array=[];
foreach ($order['product'] as $product) {
$final_array[]['total'] = (float) $product['whatever value 1 is...'];
$final_array[]['source_code'] = $product['source_code'];
}
var_dump($final_array);
If you need to apply convertCurrencyStringtoNumberbecause it does something weird to the variable then changethe seccond line to:
$final_array[]['total'] = convertCurrencyStringtoNumber(array_slice($product, 1));
i have array with database, and have to select only this items what have "tid" = 1
array(3) {
[1]=>
array(4) {
["tid"]=> "1"
["title"]=> "Google"
["url"]=> "http://google.com/"
["description"]=> "A very efficient search engine."
}
[2]=>
array(4) {
["tid"]=> "2"
["title"]=> "Facebook"
["url"]=> "http://facebook.com/"
["description"]=> "Trade securities, currently supports nearly 1000 stocks and ETFs"
}
[3]=>
array(4) {
["tid"]=> "1"
["title"]=> "Yandex"
["url"]=> "http://yandex.ru/"
["description"]=> "Another efficient search engine popular in Russia"
}
}
how can i select only this items from array what have "tid" = 1?
<?php
$final_arr = array();
foreach($tid_arrs as $tid_arr){
if($tid_arr['tid'] == 1){
$final_arr[] = $tid_arr;
}
}
print_r($final_arr);
?>
$filteredArray = array();
for($i = 0, $end = count($array);$i < $end;i++)
{
if($array[$i]["tid"] === "1")
{
$filderedArray[] = $array[$i];
}
}
That way $filteredArray will contain solely the items with tid 1;
Try array_filter function: http://php.net/manual/en/function.array-filter.php this should help.
print_r(array_filter($array, "filter_function"));
function filter_function($element){
return (int)$element['tid'] === 1;
}
let's say you starting array is $arr.
$result = array();
foreach ($arr as $arrItem) {
if ((array_key_exists('tid', $arrItem)) && ($arrItem['tid'] == "1")){
$result[] = $arrItem;
}
}
$result should be what you are excepted.
I'm going to be crazy, I can't understand what is the problem.
I have this array:
array(2) {
[0]=>
array(4) {
["id"]=>
string(1) "1"
["parent_id"]=>
NULL
["name"]=>
string(7) "Events"
["children"]=>
array(2) {
[0]=>
array(3) {
["id"]=>
string(1) "2"
["parent_id"]=>
string(1) "1"
["name"]=>
string(9) "Concerts"
}
}
}
[1]=>
array(4) {
["id"]=>
string(1) "4"
["parent_id"]=>
NULL
["name"]=>
string(7) "Music"
["children"]=>
array(3) {
[0]=>
array(3) {
["id"]=>
string(1) "5"
["parent_id"]=>
string(1) "4"
["name"]=>
string(4) "Rock"
}
}
}
}
and I try to print with this recursive function:
public function printTree($tree) {
$result = "";
if(!is_null($tree) && count($tree) > 0) {
$result .= '<ul>';
foreach($tree as $node) {
$result .= '<li>Cat: '.$node['name'];
$subtree = array($node['children']);
$this->printTree($subtree);
$result .= '</li>';
}
$result .= '</ul>';
}
return $result;
}
I get an "Undefined index: name" error.
Do I need to declare name? how?
Is the array with incorrect syntax?
If I comment the recursive call
$subtree = array($node['children']);
$this->printTree($subtree);,
then $node['name'] isn't undefined and the code works, but of course with only with one level of depth.
SOLVED: (Thanks all guys!)
public function printTree($tree) {
$result = "";
if(is_array($tree) && count($tree) > 0) {
$result .= '<ul>';
foreach($tree as $node) {
$result .= '<li>Cat: '.$node['name'];
if (isset($node['children'])) {
$result .= $this->printTree($node['children']);
}
$result .= '</li>';
}
$result .= '</ul>';
}
return $result;
}
You are pushing $node['children'] into an additional array. That way you are not dealing with the subarray of this node (which has a name later on), but you have another layer of array.
Skip this array layer, remove it.
Also note that !is_null() isn't really a nice check if you then want to use that variable as an array. Check for is_array() instead, because strings and other scalar values will return count>0 as well - they return 1. Only NULL returns count=0.
You will have to append the results returned by the consecutive calls to printTree() for child nodes to the $result.
$result .= $this->printTree($node['children']);
:)
First of all, you want to enclose the $subtree-stuff into an if-condition checking for the existence of the key 'children', because as it is now, you have created an infinite loop of recursive calls to printTree(), but you only want to do this, if the key 'children' exists.
Second, I guess you want to add $result .= in front of $this->printTree($subtree);, otherwise the return value will simply be discarded.
Third, don't do $subtree = array($node['children']);. $node['children'] already is an array, so this adds another level to the array, which makes the recursion break.
So, the final function should look something like this:
public function printTree($tree) {
$result = '';
if(!is_null($tree) && count($tree) > 0) {
$result .= '<ul>';
foreach($tree as $node) {
$result .= '<li>Cat: '.$node['name'];
if (isset($node['children'])) {
$subtree = $node['children'];
$result .= $this->printTree($subtree);
}
$result .= '</li>';
}
$result .= '</ul>';
}
return $result;
}
Edit: Whoops, was too slow there, the others also found the three problems here :)
Basically, i'm trying to get users data from a database using a class i found, it's parsing all data inside an array as shown here from the following function :
public function Get($field = NULL) {
if ($field == NULL)
{
$data = array();
while ($row = mysql_fetch_array($this->last_query))
{
$data[] = $row;
}
}
else
{
$row = mysql_fetch_array($this->last_query);
$data = $row[$field];
}
return $data;
}
Here's the PHP code i'm using to get the call this function
if($_SERVER['REQUEST_METHOD'] == 'POST'){
if($_SESSION['csrfToken'] == $_POST['csrfToken']) {
$email = $_POST['email'];
$password = $Security->Salt($Security->secParam($_POST['password']));
$DB->Query("SELECT * FROM `table` WHERE `email` = '$email' AND `password` = '$password'");
if($DB->num_rows() > 0) {
$results = $DB->Get();
} else {
echo "Account not found";
}
}
}
If i do a var_dump on $results it shows the following
array(1) {
[0]=> array(8) {
[0]=> string(1) "1" ["id"]=> string(1) "1"
[1]=> string(35) "email#email.com" ["email"]=> string(35) "email#email.com"
[2]=> string(32) "4f14dfef1efe0de64e2b176eac6051cd" ["password"]=> string(32) "4f14dfef1efe0de64e2b176eac6051cd"
[3]=> string(1) "1" ["status"]=> string(1) "1"
}
}
how can i access this data ? I've tried calling it by doing the following
$email = $results['email'];
echo $email;
But it's not displaying anything ?
Even though there's only one result in this instance (I guess?) the array supports multiple.
So find the first result, then take the email from that:
echo $results[0]['email'];
// ^^^^^^^^^^^
// first result
You need to tracking how arrays works. First you have array(1) and then into array another vars such as "email" or 1.
array(1) { <---- THIS IS ARRAY OCCURED FOR FIRST "0" ARRAY.
What's about
this
\/
echo $results[0]["email"]; ?
if($_SERVER['REQUEST_METHOD'] == 'POST' && $_SESSION['csrfToken'] == $_POST['csrfToken']) {
$password = $Security->Salt($Security->secParam($_POST['password']));
$password = $DB->quoteStr($password);
$email = $DB->quoteStr($_POST['email']);
$DB->Query("SELECT * FROM `table` WHERE `email` = $email AND `password` = $password");
return $DB->GetRow();
}
public function GetRow() {
return mysql_fetch_array($this->last_query);
}
public function quoteStr($str) {
return "'".mysql_real_escape_string($str)."'";
}
Marin Sagovac question is the answer.
To break it down a little more, your var_dump output shows that $results is a nested array. The first part of the output:
array(1) {
[0]=>
shows that $results consists of an array containing 1 element, at index 0, since that's where PHP starts indexing. This is the $results[0] part of Marin's response.
The element 0 of the $results array consists of an array with 8 elements.
[0]=>array(8) {
[0]=> string(1) "1" ["id"]=> string(1) "1"
[1]=> string(35) "email#email.com" ["email"]=> string(35) "email#email.com"
Even though there are only 4 actual results, index 1-4, each one exists twice so that they can either be accessed by index or by its key. Arrays that can be accessed by a unique key, as opposed to an index, are known as associative arrays.
So, in this case, either will return the same value:
echo $results[0]["email"];
echo $results[0][1];
The print_r function would also work, instead of var_dump.