How to push array within another array - php

I want to store sub category name and products related to that particular subcategory in array.
Below is my code,
f ($sub_category->num_rows > 1) {
while ($row = mysqli_fetch_array($sub_category)) {
$subcategory_id = $row['sub_cat_id'];
$subcategory_name['sub_category_name'][] = $row['sub_cat_name'];
$sql_subrec = "SELECT es_product_description.name AS prod_name FROM es_product_to_category LEFT JOIN es_product_description ON es_product_description.product_id=es_product_to_category.product_id LEFT JOIN es_product ON es_product_description.product_id = es_product.product_id WHERE es_product_to_category.category_id = $subcategory_id AND es_product.status=1";
//echo "<pre>";print_r($sql_subrec);
$sub_product = $conn->query($sql_subrec);
while ($prow = mysqli_fetch_assoc($sub_product)) {
$subcategory_name['sub_category_name']['products_name'][] = $prow['prod_name'];
}
}
//$subcategory_name[] = array('product_data' => $subcategory_name,);
//echo "<pre>";print_r($subcategory_name);
echo "<pre>";print_r($subcategory_name);
}
Result is not coming as expected.
I want to get products inside related subcategory array but it is coming everything in first array.
Array
(
[sub_category_name] => Array
(
[0] => Weighing Scale
[products_name] => Array
(
[0] => BS-250 Baby Scale
[1] => DS-415N Bench Scale
[2] => DS-415N Platform Scale
[3] => DS-65 Counter Scale
[4] => DS-852 Weighing Scale
[5] => DS-252 Weighing Scale
[6] => DS-215N Platform Scale
[7] => DS-75 Counter Scale
[8] => DS-415 Smile
[9] => DS-215SS Platform Scale
[10] => DS-450 Table Top Weighing Scale
[11] => DS-450SS Bench Scale
[12] => DS-451HP Weighing Scale
[13] => DS-215 Hanging Scale
[14] => DS-215N Trolley Scale
[15] => DS-673 Weighing Scale
[16] => DS-315 Series Crane Scale
[17] => DS-515 Weighing Scale
[18] => DS-450CW Check Weigher Scale
[19] => DC-810 Counting, Barcode Printing Scale
[20] => DC-85 Counting Scale
[21] => DS-252C Counting Scale
[22] => DC-810 Counting, Barcode Printing Scale
[23] => SI-810 Label Printing Scale
[24] => SI-810PR Receipt Printing
[25] => DS-252PR Receipt Printing Scale
[26] => Barcode Label Printer Scales
[27] => Receipt Printer Scales
[28] => SI-810PR Barcode Label Printer Scale
[29] => SM - 100EV+ Barcode Label Printer Scale
[30] => SI-810PRSS Receipt Printer Scale
[31] => SI-810PR Receipt Printer Scale
[32] => DS-252PR Receipt Printer Scale
[33] => DC-810 Counting, Barcode Printing Scale
[34] => SI-810 Label Printing Scale
[35] => DS-451TW Tank/Vessel Weighing
[36] => DS-451 Milk Weighing
[37] => SI-810 System Scale Bench Type
[38] => SI-810 System Scale Platform Type
[39] => HT-HTR Series Analytical Balance
[40] => MX-50 Moisture Analyzer
[41] => AJ Series Precision Balance
[42] => PG/FB Precision Balance
[43] => DS-852G Precision Balance
[44] => LF-225DR Semi-micro balance
)
[1] => Industrial Counting Scale
[2] => Retail Printer Scale
[3] => Weighing System & Solutions
[4] => Weighing Balance
)
)

As far as I understand from you limited explanation you might just need to do something like this in your second while:
$subcategory_name['sub_category_name'][$row['sub_cat_name']]['products_name'][] = $prow['prod_name'];
But this is just a guess... please post the expected output and the actual one.

Try this. 'Sub Category Name' & 'Product Name' comes under single 'Sub Category ID' keyindex
if ($sub_category->num_rows > 1){
while ($row = mysqli_fetch_array($sub_category)){
$subcategory_id = $row['sub_cat_id'];
$subcategory_name[$subcategory_id]['sub_category_name'][] = $row['sub_cat_name'];
$sql_subrec = "SELECT es_product_description.name AS prod_name FROM es_product_to_category LEFT JOIN es_product_description ON es_product_description.product_id=es_product_to_category.product_id LEFT JOIN es_product ON es_product_description.product_id = es_product.product_id WHERE es_product_to_category.category_id = $subcategory_id AND es_product.status=1";
//echo "<pre>";print_r($sql_subrec);
$sub_product = $conn->query($sql_subrec);
while ($prow = mysqli_fetch_assoc($sub_product)){
$subcategory_name[$subcategory_id]['products_name'][] = $prow['prod_name'];
}
}
echo "<pre>";print_r($subcategory_name);
}

Related

PHP - concatenate ' checked' to each string value in multidimensional array using recursion

I have a multidimensional array in PHP, and want to concatenate a string onto each string element using recursion. The array is as follows:
$array = Array
(
[p] => Array
(
[0] => This Porsche 993 Carrera Cabriolet represents a great opportunity to acquire an open-top variant of one of the most coveted 911 models.
[1] => First registered on 5 August 1994, M912 SGY displays 10,630 miles on the odometer with a clock change at 66,244 miles in 2014.
[2] => The car’s Aventura Green metallic paintwork is reported to be in good condition, presenting well for its age and mileage.
[3] => The Marble Grey leather interior is believed to be entirely original.
[4] => Serviced by Porsche specialist Portiacraft in July 2020 at 76,598 miles, this consisted of an annual oil and filter service.
[5] => The last MOT was undertaken on 6 July 2020 at 76,598 miles.
[6] => It is supplied with a Porsche Club Great Britain folder with records of main dealer and specialist service history.
[7] => This Porsche 911 Carrera Cabriolet presents in highly original and well-maintained condition.
[8] => Summary of maintenance history:
[9] => Array
(
[strong] => The description of this auction lot is, to the best of the seller's knowledge, accurate and not misleading.
)
[10] => Array
(
[strong] => All UK-registered cars and motorbikes on Collecting Cars are run through an online HPI check. This vehicle shows no insurance database markers for damage or theft, and has no finance owing.
)
)
[ul] => Array
(
[li] => Array
(
[0] => 04/11/1996 – 16,120 miles
[1] => 18/11/1998 – 25,086 miles
[2] => 09/09/1999 – 28,769 miles
[3] => 21/02/2000 – 31,469 miles
[4] => 22/06/2001 – 36,055 miles
[5] => 29/10/2002 – 40,781 miles
[6] => 02/03/2005 – 46,238 miles
[7] => 24/03/2006 – 49,459 miles
[8] => 03/07/2007 – 53,051 miles
[9] => 17/12/2008 – 56,582 miles
[10] => 20/05/2010 – 57,385 miles
[11] => 08/06/2011 – 61,653 miles
[12] => 15/05/2012 – 64,425 miles
[13] => 17/04/2013 – 66,026 miles
[14] => 07/06/2014 – 66,244 miles
[15] => 14/09/2015 – 68,411 miles
[16] => 27/02/2018 – 74,856 miles
[17] => 06/08/2019 – ~76,400 miles
[18] => 06/07/2020 – 76,598 miles
)
)
)
Ideally, the result should look like this:
$array = Array
(
[p] => Array
(
[0] => This Porsche 993 Carrera Cabriolet represents a great opportunity to acquire an open-top variant of one of the most coveted 911 models. checked
[1] => First registered on 5 August 1994, M912 SGY displays 10,630 miles on the odometer with a clock change at 66,244 miles in 2014. checked
[2] => The car’s Aventura Green metallic paintwork is reported to be in good condition, presenting well for its age and mileage. checked
[3] => The Marble Grey leather interior is believed to be entirely original. checked
[4] => Serviced by Porsche specialist Portiacraft in July 2020 at 76,598 miles, this consisted of an annual oil and filter service. checked
[5] => The last MOT was undertaken on 6 July 2020 at 76,598 miles. checked
[6] => It is supplied with a Porsche Club Great Britain folder with records of main dealer and specialist service history. checked
[7] => This Porsche 911 Carrera Cabriolet presents in highly original and well-maintained condition. checked
[8] => Summary of maintenance history: checked
[9] => Array
(
[strong] => The description of this auction lot is, to the best of the seller's knowledge, accurate and not misleading. checked
)
[10] => Array
(
[strong] => All UK-registered cars and motorbikes on Collecting Cars are run through an online HPI check. This vehicle shows no insurance database markers for damage or theft, and has no finance owing. checked
)
)
[ul] => Array
(
[li] => Array
(
[0] => 04/11/1996 – 16,120 miles checked
[1] => 18/11/1998 – 25,086 miles checked
[2] => 09/09/1999 – 28,769 miles checked
[3] => 21/02/2000 – 31,469 miles checked
[4] => 22/06/2001 – 36,055 miles checked
[5] => 29/10/2002 – 40,781 miles checked
[6] => 02/03/2005 – 46,238 miles checked
[7] => 24/03/2006 – 49,459 miles checked
[8] => 03/07/2007 – 53,051 miles checked
[9] => 17/12/2008 – 56,582 miles checked
[10] => 20/05/2010 – 57,385 miles checked
[11] => 08/06/2011 – 61,653 miles checked
[12] => 15/05/2012 – 64,425 miles checked
[13] => 17/04/2013 – 66,026 miles checked
[14] => 07/06/2014 – 66,244 miles checked
[15] => 14/09/2015 – 68,411 miles checked
[16] => 27/02/2018 – 74,856 miles checked
[17] => 06/08/2019 – ~76,400 miles checked
[18] => 06/07/2020 – 76,598 miles checked
)
)
)
I have tried the following:
$addedChecked = $this->addCheckedRecursive($array);
private function addCheckedRecursive($array)
{
if(!is_array($array)) {
return $array . ' checked';
}
foreach($array as $v) {
$this->addCheckedRecursive($v);
}
}
and also
$addedChecked = array_walk_recursive($array, function (&$value) {
$value .= ' checked';
});
The latter simply returned true.
For info, every element of each array will always be a string, and I would also like to preserve the current array structure. Any help is appreciated.
There is an in-built function that you can use to achieve what you want.
If you use array_walk_recursive as follows:
// Say you have your array $xmlArray
array_walk_recursive($xmlArray, function (&$value) {
$value .= ' checked';
});
// Since $xmlArray is now modified (in place)
echo '<pre>';
print_r($xmlArray);
echo '</pre>';
In case you would not want $xmlArray to be changed as a side effect, could assign a value copy of the array to a new variable.
$addedChecked = $xmlArray;
array_walk_recursive($addedChecked, function (&$value) {
$value .= ' checked';
});
// Since $addedChecked is now modified (in place)
echo '<pre>';
print_r($addedChecked);
echo '</pre>';
The function takes in the array by reference and will thus modify the array directly as a side effect of the function. This is one important thing to note, it does not return an array, but only whether the function was successfully executed on the array you gave it.
This will loop over each key => value pair and do so recursively if the value is of type array. You can simply concatenate to the value (where we pass value by reference) to update it with checked.
why dont you try array_walk_recursive or array_replace_recursive ?
the docs can be found here
Try it like this:
$addedChecked = $this->addCheckedRecursive($array);
private function addCheckedRecursive($array)
{
if (!is_array($array)) {
return $array . ' checked';
}
else
{
for ($i = 0; $i < count($array); $i++) {
$array[$i] = $this->addCheckedRecursive($array[$i]);
}
return $array;
}
}

Scaling and normalizing data using logarithmic scale

I want to create a rank system for users on my website. The ranks will be decided by a number of factors like how long they've been a member, how many posts they created etc. Every data item is also divided by a "weight" determined by me, so that it is more representative of the actual user activity - I don't want 1 post be as significant as 1 day as a member. After the weighing all stats are added together to a total.
Then, I have to normalize the totals so that they are assigned to the ranks which range from 1 to 20, since some members have just a few points of activity and some veteran members have thousands of points. I do this by normalizing the data and scaling it down to the 1-20 rank range with this function:
function normalize($userTotal, $minOriginalRange, $maxOriginalRange, $minNewRange, $maxNewRange){
return $minNewRange + ((($maxNewRange - $minNewRange) * ($originalValue - $minOriginalRange)) / ($maxOriginalRange - $minOriginalRange));
}
This is usually called like so:
normalize(getUserTotal(), 0, getHighestTotalOfAllMembers(), 1, 20);
And so I got this as a result, key is rank and value is number of members who would get that rank:
Array
(
[1] => 7418
[2] => 1918
[3] => 289
[4] => 102
[5] => 62
[6] => 28
[7] => 21
[8] => 14
[9] => 1
[10] => 8
[11] => 6
[12] => 5
[13] => 1
[14] => 1
[17] => 1
[20] => 1
)
As you can see there are tons of users who are ranked low and very few who get assigned the mid and high ranks. I'd like to fix this by calculating the rank assigned using a logarithmic scale, so that it is easy to climb the ranks in the lower tiers and gets harder and harder the higher you go. That way it should spread out more evenly and more users will have ranks in the middle.
I don't know how to approach this however, I have never used logarithmic scales and always resorted to simple arithmetic in my code.
You would use a php math logarithm function and map it over the final array, for example:
function logfunction($v){
return round(log1p($v),2);
}
$simple_array = [7418, 1918, 289, 102, 62, 28, 21, 14, 1, 8, 6, 5, 1, 1, 1];
$logarithmic_array = array_map(logfunction, $simple_array);
print_r($logarithmic_array);
In the above, I use the log1p() function whichreturns log(1 + number) computed in a way that is accurate even when the value of number is close to zero (See: http://php.net/manual/en/function.log1p.php). Then I round the result to 2 decimal places for the sake of readability. The resulting $logarithmic_array output is:
Array
(
[0] => 8.91
[1] => 7.56
[2] => 5.67
[3] => 4.63
[4] => 4.14
[5] => 3.37
[6] => 3.09
[7] => 2.71
[8] => 0.69
[9] => 2.2
[10] => 1.95
[11] => 1.79
[12] => 0.69
[13] => 0.69
[14] => 0.69
)

preg match all in array searching for [ ]

i have found the solution mysqlf using:
foreach ($output as $value) {
if (strpos($value, "]:") > -1) {
$tal = substr($value, strpos($value, "]:") +3) . "<br>";
echo $tal;
}
}
this returns:
-210
-212
Thanks in advance.
I want to preg so i only get the line: [10] => [147]: -210
or both [10] => [147]: -210 and [21] => [148]: -212
how can i preg [147]: or is there a better way to get the specific information?
my array $output contains:
Array
(
[0] => modpoll 3.4 - FieldTalk(tm) Modbus(R) Master Simulator
[1] => Copyright (c) 2002-2013 proconX Pty Ltd
[2] => Visit http://www.modbusdriver.com for Modbus libraries and tools.
[3] =>
[4] => Protocol configuration: MODBUS/TCP
[5] => Slave configuration...: address = 1, start reference = 147, count = 1
[6] => Communication.........: 10.234.6.11, port 502, t/o 1.00 s, poll rate 1000 ms
[7] => Data type.............: 16-bit register, output (holding) register table
[8] =>
[9] => -- Polling slave...
[10] => [147]: -210
[11] => modpoll 3.4 - FieldTalk(tm) Modbus(R) Master Simulator
[12] => Copyright (c) 2002-2013 proconX Pty Ltd
[13] => Visit http://www.modbusdriver.com for Modbus libraries and tools.
[14] =>
[15] => Protocol configuration: MODBUS/TCP
[16] => Slave configuration...: address = 1, start reference = 148, count = 1
[17] => Communication.........: 10.234.6.11, port 502, t/o 1.00 s, poll rate 1000 ms
[18] => Data type.............: 16-bit register, output (holding) register table
[19] =>
[20] => -- Polling slave...
[21] => [148]: -212
)
$matches = preg_grep ('/^[147] (\w+)/i', $output);
print_r ($matches);
//only returns Array()
You need to escape the opening square bracket because [147] is seen as a character class that contains 1, 4 and 7
You can do this with:
$result=preg_grep('~^\[14(?:7|8)]:~',$rgData);
print_r($result);
You can find all that you want to know about escaping (or not) square brackets here

Can't read csv(Tab delimited) properly

I have simple csv file which is tab delimited which i have to use as it is because it is coming from somewhere and i hvae to read it and insert it into my db i have used a simple php code to read it
if(($handle = fopen("var/import/MMT29DEC.csv","r"))!==FALSE){
/*Skip the first row*/
fgetcsv($handle, 1000,chr(9));
while(($data = fgetcsv($handle,1000,chr(9)))!==FALSE){
print_r($data[0]);
}
}
When print_r the data it shows like
Array ( [0] => 01SATAPC [1] => 40ATAPC [2] => [3] => 21P [4] => SERIAL ATA POWER CABLE [5] => 0.00 [6] => 2.00 [7] => 0 [8] => Power Supplies [9] => SERIAL ATA POWER CABLE [10] =>
4 TO 15 PIN 160MM
[11] => [12] => [13] => [14] => MELBHO [15] => 0.000 [16] => [17] => Order to Order [18] => 4 [19] => 2013-01-18 )
Which is the desired result but when i go to access the particular column value using the $data['index'] e.g. $data[8] or $data[1] it weirdly giving me garbage values says for some iterations it give me right values but after 10-15 rows its starting giving me the some numbers and other column values..... i don't know whats is going on with this as far as i know it should be formatting issue i have tried open the file in excel and its coming fine....
#ravisoni are you sure that the second parameter to fgetcsv of 1000 is longer than the longest line in your file? Try setting it to 0 as the docs say [php.net/fgetcsv] and see if that makes a difference.
if(($handle = fopen("var/import/MMT29DEC.csv","r"))!==FALSE){
/*Skip the first row*/
fgetcsv($handle, 0,chr(9));
while(($data = fgetcsv($handle,0,chr(9)))!==FALSE){
print_r($data[0]);
}
}

how to get sort array according to another array in php

i have one script, in which i have this fields DId(not auto increment) ,Rating ,they are comma separated, the ratings are come from database. now i have to display highest 5 values of ratings and devices according to the ratings.i can find max values of ratings by rsort method then slice the array to 5,but problem is that how can i get the DId according to the ratings. because when rsort an array i lost original indexes of that array, and this script is based on database, and devices will be changed according to the rating each time ratings will be changed. here what i did so far
$query=mysql_query("SELECT DId,Rating FROM wp_ratings1 WHERE QID='1' LIMIT 5,1");
$row=mysql_fetch_array($query);
$no1=explode(",",$row['DId']);
$array_size=count($no1);
$list = $row['Rating'];
$array = explode(',', $list);
rsort($array);
$res=array_slice($array,0,5);
print_r($array);
DId || Rating||
36,37,38, 2.3,2.3,4.5,
39,41,42, 1.0,0,0,
43,44,45, 3.4,1.2,3.12,
46,52,53 || 2.33,1.22,0.9
Welcome to SO!
In your case, I would parse the data and supply it into variable like this:
$arrData[0] = array(36=>2.3, 37=>2.3, 38=>4.5);
$arrData[1] = array(39=>1, 41=>0, 42=>0);
$arrData[2] = array(43=>3.4, 44=>1.2, 45=>3.12);
$arrData[3] = array(46=>2.33, 52=>1.22, 53=>0.9);
and then process each element and turn it into single array:
$arrNew = array();
foreach($arrData as $data){
foreach($data as $key=>$rating){
$arrNew[$key]=$rating;
}
}
finally, do asort() on that array.
print_r($arrNew);
asort($arrNew);
print_r($arrNew);
This is my test result:
Array
(
[36] => 2.3
[37] => 2.3
[38] => 4.5
[39] => 1
[41] => 0
[42] => 0
[43] => 3.4
[44] => 1.2
[45] => 3.12
[46] => 2.33
[52] => 1.22
[53] => 0.9
)
Array
(
[41] => 0
[42] => 0
[53] => 0.9
[39] => 1
[44] => 1.2
[52] => 1.22
[36] => 2.3
[37] => 2.3
[46] => 2.33
[45] => 3.12
[43] => 3.4
[38] => 4.5
)
A cleaner solution would be to use user defined sort :
http://php.net/manual/en/function.usort.php

Categories