Sort array data without duplicate - php

I'm making a twitter bot using Codebird.
I want to sort the data status in php array without duplicates. Line by line (urls media /remote file links)
This my code:
require_once ('codebird.php');
\Codebird\Codebird::setConsumerKey("pubTRI3ik5hJqxxxxxxxxxx", "xxxxxS6Uj1t5GJPi6AUxxxxx");
$cb = \Codebird\Codebird::getInstance();
$cb->setToken("xxxxxxx-aVixxxxxxxxxX5MsEHEK", "Dol6RMhOYgxxxxxxFnDtJ6IzXMOLyt");
$statusimgs = array (
"/images.com/hfskehfskea33/jshdfjsh.jpeg",
"/pic.images.com/SDjhs33/sZddszf.jpeg",
"/pic.images.com/dfggfd/dgfgfgdg.jpeg",
"//pic.images.com/xgxg/xdgxg6.jpeg",
);
$params = array(
'status' => 'halo my ststus',
'media[]' => $statusimgs[array_rand($statusimgs)]
);
$reply = $cb->statuses_updateWithMedia($params);
Initially I use random array, but this can make duplicate photos.
I want to sort link remote files from first line to last. I have 1-100 link images to upload on twitter from remote file methot. One by one when script execute manual or with cron.
I want set cron every 60s , 60s 1 photo tweet.

I understand your question as "Remove duplicates from an array and sort it".So, you could try this:
Make $statusarray unique,
sort $statusarray,
add $statusarray to $params array (key = 'media').
Code
<?php
// Input array
$statusimgs = array (
"/images.com/hfskehfskea33/jshdfjsh.jpeg",
"/pic.images.com/SDjhs33/sZddszf.jpeg",
"/pic.images.com/dfggfd/dgfgfgdg.jpeg",
"/pic.images.com/dfggfd/dgfgfgdg.jpeg",
"/pic.images.com/xgxg/xdgxg6.jpeg",
"/pic.images.com/xgxg/xdgxg6.jpeg",
"/pic.images.com/xgxg/xdgxg6.jpeg",
);
// Make unique and sort
$statusimgs = array_unique($statusimgs, SORT_STRING);
sort($statusimgs,SORT_STRING);
// Create the resulting $params array
$params = array(
'status' => 'halo my ststus',
'media' => $statusimgs
);
// Display the result
echo '<pre>'; var_dump($params); '</pre>';
//$reply = $cb->statuses_updateWithMedia($params);
?>
Result
array(2) {
["status"]=>
string(14) "halo my ststus"
["media"]=>
array(4) {
[0]=> string(39) "/images.com/hfskehfskea33/jshdfjsh.jpeg"
[1]=> string(36) "/pic.images.com/SDjhs33/sZddszf.jpeg"
[2]=> string(36) "/pic.images.com/dfggfd/dgfgfgdg.jpeg"
[3]=> string(32) "/pic.images.com/xgxg/xdgxg6.jpeg"
}
}
Alternative Code
<?php
$statusimgs = array (
"/images.com/hfskehfskea33/jshdfjsh.jpeg",
"/pic.images.com/SDjhs33/sZddszf.jpeg",
"/pic.images.com/dfggfd/dgfgfgdg.jpeg",
"/pic.images.com/dfggfd/dgfgfgdg.jpeg",
"/pic.images.com/xgxg/xdgxg6.jpeg",
"/pic.images.com/xgxg/xdgxg6.jpeg",
"/pic.images.com/xgxg/xdgxg6.jpeg",
);
$statusimgs = array_unique($statusimgs, SORT_STRING);
sort($statusimgs,SORT_STRING);
session_start();
if (!isset($_SESSION['index'])) {
$_SESSION['index'] = 1;
} else {
$_SESSION['index'] = ($_SESSION['index']>=count($statusimgs)) ? 1 : $_SESSION['index']+1;
}
session_write_close();
$params = array(
'status' => 'halo my ststus',
'media' => $statusimgs
);
// echo '<pre>'; var_dump($params); '</pre>';
echo 'Choosen: ' . $params['media'][$_SESSION['index']-1] . '<br />';
//$reply = $cb->statuses_updateWithMedia($params);
?>

Related

Compute average value from multi array with one loop

I have some code which remove parameters from every url from array.
Then it sums a scores for every matched url-keyword and finally it shoud get average value from one of value 'position'.
Everythink works for me. But I am thinkink is there any way to do it with one loop? Now I use two loops for it.
One of them sum values for me. Then I need use a foreach and divide sum of my values by count my matched keyword-url occurred.
Maybe someone have idea how can I compute average 'position' score in one loop?
<?php
$keywordsUrlsArray = array(
0 => array
(
'url' => 'https://www.example.pl/?test=19',
'keyword' => 'test',
'score1' => 100,
'score2' => 50,
'position' => 4
),
1 => array
(
'url' => 'https://www.example.pl/?test=2',
'keyword' => 'test',
'score1' => 100,
'score2' => 50,
'position' => 1
),
2 => array
(
'url' => 'https://www.example.pl/?test=3',
'keyword' => 'test',
'score1' => 100,
'score2' => 50,
'position' => 3
),
3 => array
(
'url' => 'https://www.example.pl/other-site?test=3',
'keyword' => 'test',
'score1' => 100,
'score2' => 50,
'position' => 3
)
);
And there is code for it.
$res = array();
foreach ($keywordsUrlsArray as $urlResults) {
//remove params from url
$parsedUrl = parse_url($urlResults['url']);
$parsedUrl = $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . $parsedUrl['path'];
$keyword = $urlResults['keyword'];
if (array_key_exists($parsedUrl, $res)) {
//check if parsed url with removed parameters exists and if it has the same keyword I need to sum scores
if (isset($res[$parsedUrl][$keyword])) {
$res[$parsedUrl][$keyword]['urlCount'] += 1;
$res[$parsedUrl][$keyword]['score1'] += $urlResults['score1'];
$res[$parsedUrl][$keyword]['score2'] += $urlResults['score2'];
$res[$parsedUrl][$keyword]['position'] += $urlResults['position'];//my problem is there any way to compute my average position wtihout do a second foreach below?
continue;
}
}
$res[$parsedUrl][$keyword] = $urlResults;
$res[$parsedUrl][$keyword]['url'] = $parsedUrl;
$res[$parsedUrl][$keyword]['urlCount'] = 1;
}
//there I have to do a second foreach to compute average keyword/url position
//and compute position which will be sum of all positions divided by every matched keyword/url
$result = [];
foreach ($res as $k => $r) {
foreach ($r as $p => $t) {
$t['position'] = $t['position'] / $t['urlCount'];
unset($t['urlCount']);
$result[] = $t;
}
}
var_dump( $result);
return $result;
}
And there is my result. Sum of positions divided by occured urls.
array(2) {
[0]=>
array(5) {
["url"]=>
string(23) "https://www.example.pl/"
["keyword"]=>
string(4) "test"
["score1"]=>
int(300)
["score2"]=>
int(150)
["position"]=>
float(2.6666666666667)
}
[1]=>
array(5) {
["url"]=>
string(33) "https://www.example.pl/other-site"
["keyword"]=>
string(4) "test"
["score1"]=>
int(100)
["score2"]=>
int(50)
["position"]=>
int(3)
}
}
You can keep track of the sum of the positions, and update the position every time you have a match for the url.
At the end of your code, init the first sum to prevent missing the first match.
foreach ($keywordsUrlsArray as $urlResults) {
$parsedUrl = parse_url($urlResults['url']);
$parsedUrl = $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . $parsedUrl['path'];
$keyword = $urlResults['keyword'];
if (array_key_exists($parsedUrl, $res)) {
if (isset($res[$parsedUrl][$keyword])) {
$res[$parsedUrl][$keyword]['urlCount'] += 1;
$res[$parsedUrl][$keyword]['score1'] += $urlResults['score1'];
$res[$parsedUrl][$keyword]['score2'] += $urlResults['score2'];
$res[$parsedUrl][$keyword]['sumPosition'] += $urlResults['position'];
$res[$parsedUrl][$keyword]['position'] = $res[$parsedUrl][$keyword]['sumPosition'] / $res[$parsedUrl][$keyword]['urlCount'];
continue;
}
}
$res[$parsedUrl][$keyword] = $urlResults;
$res[$parsedUrl][$keyword]['url'] = $parsedUrl;
$res[$parsedUrl][$keyword]['urlCount'] = 1;
$res[$parsedUrl][$keyword]['sumPosition'] = $urlResults['position'];
}
It will give you the position in the same loop, but you will still have the keys urlCount and sumPosition in the final arrays.
See a php demo.

Return multidimensional array value based on most recent date and another value

I am basing my code on the following link:
PHP Multidimensional Array Searching (Find key by specific value)
I attempted to add code similar to Get most recent date from an array of dates ; however I kept receiving illegal offset errors.
I can successfully select the proper value based on the first code. How can I then narrow down my return based on the most recent date in the array?
I am using php 5.4.45 and my array is always sorted by date with the most recent being last. I cannot simply select the last array index as it is not always a "Paid" order status.
My Array:
array(4) {
[0]=> array(3) {
["status"]=> string(6) "Active"
["check_number"]=> string(0) ""
["date_added"]=> string(19) "17/11/2015 10:34:53" }
[1]=> array(3) {
["status"]=> string(4) "Paid"
["check_number"]=> string(5) "12345"
["date_added"]=> string(19) "14/12/2015 07:40:59" }
[2]=> array(3) {
["status"]=> string(8) "Invoiced"
["check_number"]=> string(0) ""
["date_added"]=> string(19) "14/12/2015 09:44:31" }
[3]=> array(3) {
["status"]=> string(4) "Paid"
["check_number"]=> string(4) "0258"
["date_added"]=> string(19) "14/12/2015 09:53:29" }
}
My code:
function getValue($fromSource, $field, $value, $get){
if ($fromSource[$field] === $value) {
return $fromSource[$get];
};
return false;
}
foreach ($order['order_history'] as $order_history) {
var_dump(getValue($order_history, "status", "Paid", "check_number"));
}
Desired result: "0258" (where status = "Paid" and date = most recent)
Currently Receiving: "12345" "0258" (where status = "Paid")
Using array_walk we collect all the dates.
We transform the dates into timestamps, using createFromFormat and getTimestamp, so we can easily order them, not forgetting to pass a timezone.
We get the key of the highest timestamp, and use it to access the list of items.
$items being the initial array.
$dates = array();
$format = 'd/m/Y H:i:s';
$timezone = new DateTimeZone('UTC');
array_walk($items,function($item,$index) use(&$dates,$format,$timezone){
$date = DateTime::createFromFormat($format, $item["date_added"],$timezone);
$dates[$index] = $date->getTimestamp();
});
// get the key of the most recent date
$key = array_keys($dates, max($dates))[0];
// using the key get the item from the list
print_r($items[$key]) . PHP_EOL;
Will output
Array
(
[status] => Paid
[check_number] => 0258
[date_added] => 14/12/2015 09:53:29
)
From here you can easily access only one element of the result
print $items[$key]["check_number"];
Will output
0258
I think another possibility is to loop your array with a foreach construct and check for every array in the iteration if "status" is "Paid".
Then every iteration you can compare the date from the current $item with the date in the $result array by using a DateTime object.
For example:
$items = array(
array(
"status" => "Active",
"check_number" => "",
"date_added" => "17/11/2015 10:34:53"
),
array(
"status" => "Paid",
"check_number" => "12345",
"date_added" => "14/12/2015 07:40:59"
),
array(
"status" => "Invoiced",
"check_number" => "",
"date_added" => "14/12/2015 09:44:31"
),
array(
"status" => "Paid",
"check_number" => "0258",
"date_added" => "14/12/2015 09:53:29"
)
);
$result = array();
foreach ($items as $item) {
if ($item["status"] === "Paid") {
// If there is no result yet with status "Paid", then add it.
if (count($result) === 0) {
$result = $item;
continue;
}
$itemDateTime = DateTime::createFromFormat('d/m/Y H:i:s', $item["date_added"]);
$resultDateTime = DateTime::createFromFormat('d/m/Y H:i:s', $result["date_added"]);
if ($itemDateTime > $resultDateTime) {
$result = $item;
}
}
}
var_dump($result);
Will result in:
array (size=3)
'status' => string 'Paid' (length=4)
'check_number' => string '0258' (length=4)
'date_added' => string '14/12/2015 09:53:29' (length=19)
Then you can access your value from the $result array like this:
echo $result["check_number"];
Will result in:
0258
Demo
If the array is always sorted, you can use this code to get the newest entry matching the corresponding status:
function getLatest($arr, $field, $value, $getField){
for($i=count($arr)-1;$i >= 0; $i--){
$currSubArr = $arr[$i];
if($currSubArr[$field] === $value){
return $currSubArr[$getField];
}
}
}
$orders[] = array('status' => 'active', 'checknumber'=> '121234','date_added' => '17/11/2015 10:34:53');
$orders[] = array('status' => 'paid', 'checknumber' => '1212334','date_added' => '17/11/2015 10:38:53');
$orders[] = array('status' => 'paid', 'checknumber '=> '5234','date_added' => '17/11/2015 10:42:53');
//test --> returns 5234
echo getLatest($orders,'status','paid','checknumber');

PHP - Recursively set each array element's key to the value of a child element when given the childs key name

I'll start by showing a non-recursive example
Non- recursive example
$given_key_name = 'site_id';
$rows[] = array(
'site_id' => '0',
'language_id' => '1',
'name' => 'sitename',
'description' =>'site desc',
);
$results = array();
foreach($rows as $row){
$key_value = $row[$given_key_name];
unset($row[$given_key_name]);
$results[$key_value] = $row;
}
// OR This method is faster than the forloop
$results = array_combine(array_column($rows, $given_key_name),$rows);
foreach($results as &$row){
unset($row[$given_key_name]);
}
$results Equals
$results[0] = array(
'language_id' => '1',
'name' => 'sitename',
'description' =>'site desc',
);
Simple, the key name has been set to the value of the given child element. But I would like to be able to nest and unnest by using multiple key names.
Example
$given_key_names = array('site_id', 'language_id');
In this case the required result would be.
$results[0][1] = array(
'name' => 'sitename',
'description' =>'site desc',
);
Explanation
The first keys value has been used as the first key in the $results array and a new empty array is created as its value. $results[0] = array();
As there is a second key, its value is set as a key to the newly created array and its value is also a new empty array. $results[0][1] = array();
As there are no more keys the empty array is populated with the remaining values
$results[0][1] = array(
'name' => 'sitename',
'description' =>'site desc',
);
so i would like two functions nestByKeyNames and unNestByKeyName.
NestByKeyNames Function
Christians Answer solves this
function nestByKeyNames($arrayRows, $arrayKeyOrder){
// Prepare resulting array
$arrayResult = array();
// Cycle the input array
foreach($arrayRows as $someRow){
// We will acomplish this using references
$current = &$arrayResult;
// get the current level
foreach($arrayKeyOrder as $someKey){
$someValue = $someRow[$someKey];
if(isset($current[$someValue])){
$current = &$current[$someValue];
}else{
$current[$someValue] = array();
$current = &$current[$someValue];
}
unset($someRow[$someKey]);
}
$current = $someRow;
}
return $arrayResult;
}
I wonder whether array_combine(array_column($arrayRows, $key_name),$arrayRows); could be used instead of the first iteration to improve performance?
This represents the results from a mysql select statement.
$rows = array(
array(
'pri_id_1' =>1,
'pri_id_2' =>1,
'pri_id_3' =>1,
'col_1' =>'col_value_1111',
'col_2' =>'col_value_1112',
'col_3' =>'col_value_1113',
),
array(
'pri_id_1' =>1,
'pri_id_2' =>2,
'pri_id_3' =>1,
'col_1' =>'col_value_1211',
'col_2' =>'col_value_1212',
'col_3' =>'col_value_1213',
),
array(
'pri_id_1' =>1,
'pri_id_2' =>3,
'pri_id_3' =>1,
'col_1' =>'col_value_1311',
'col_2' =>'col_value_1312',
'col_3' =>'col_value_1313',
)
);
$keyNames = array('pri_id_1','pri_id_2','pri_id_3');
$results = nestByKeyNames($rows, $keyNames);
The following output is produced
Array
(
[1] => Array
(
[1] => Array
(
[1] => Array
(
[col_1] => col_value_1111
[col_2] => col_value_1112
[col_3] => col_value_1113
)
)
[2] => Array
(
[1] => Array
(
[col_1] => col_value_1211
[col_2] => col_value_1212
[col_3] => col_value_1213
)
)
[3] => Array
(
[1] => Array
(
[col_1] => col_value_1311
[col_2] => col_value_1312
[col_3] => col_value_1313
)
)
)
)
UnNestByKeyNames Function
unNestByKeyNames should be able to take this output and convert it back to the original array providing that it is given the key names.
Christians Answer did not solves this as it doesnt work with a single key name but i can tell its very close.
function unNestByKeyNames($arrayRows, $arrayKeyOrder){
}
$keyNames = array('pri_id_1','pri_id_2','pri_id_3');
$rows = unNestKeyNames($results, $keyNames);
My true goal is to take the results from MYSQL SELECT statement and populate a form using the same naming convention by using nestByKeyNames.
e.g.
<input name="rows[1][1][1][col_1]" value="col_value_1" />
and then convert the $_POST request back into an MYSQL INSERT statement by first using unNestByKeyNames.
From this i will create an INSERT statement.
function returnValues($rows, $column_names){
//validation has been removed for clarity
$implode_VALUES = array();
foreach ($rows as $key => $row) {
$implode_row_values = array();
foreach ($column_names as $column_name) {
$implode_row_values[$column_name] = $row[$column_name];
}
if($implode_row_values){
$implode_VALUES[] = " ('" . implode("','", $implode_row_values) . "') ";
}
}
return $implode_VALUES;
}
$implode_COLUMNS = array('pri_id_1','pri_id_2','pri_id_3','col_1','col_2','col_3');
$implode_VALUES = returnValues($rows, $implode_COLUMNS)
$sql = "INSERT INTO table_name (" . implode(',', $implode_COLUMNS) . ") VALUES " . implode(',', $implode_VALUES);
The final result should produce a sql statement like so
INSERT INTO table_name (pri_id_1,pri_id_2,pri_id_3,col_1,col_2,col_3) VALUES ('1','1','1','NEW_value_1111','NEW_value_1112','NEW_value_1113') , ('1','2','1','NEW_value_1211','NEW_value_1212','NEW_value_1213') , ('1','3','1','NEW_value_1311','NEW_value_1312','NEW_value_1313')
What I Would like
Improvement suggestions on the 'nestByKeyNames' function (performance/ does it have bugs)
help producing 'unNestByKeyNames' code
Improvement suggestions on my '$rows to mysql INSERT' approach
examples of how i could make any of my code perform better.
This was trickier than I first imagined but I believe I have a messy solution.
First of all, this is the data I am working with. dumpr is a custom function that formats var_dump better.
$arrayKeyOrder = array(
'site_id',
'language_id'
);
$original = array(
array(
'site_id' => '0',
'language_id' => '1',
'name' => 'sitename',
'description' =>'site desc',
),
array(
'site_id' => '0',
'language_id' => '2',
'name' => 'sitename',
'description' =>'site desc',
),
array(
'site_id' => '1',
'language_id' => '1',
'name' => 'sitename',
'description' =>'site desc',
),
array(
'site_id' => '2',
'language_id' => '1',
'name' => 'sitename',
'description' =>'site desc',
),
);
$zipped = doZip($original, $arrayKeyOrder);
$unzipped = unZip($zipped, $arrayKeyOrder);
dumpr($original);
dumpr($zipped);
dumpr($unzipped);
Here is the zip and unzip functions:
function doZip($arrayRows, $arrayKeyOrder){
// Prepare resulting array
$arrayResult = array();
// Cycle the input array
foreach($arrayRows as $someRow){
// We will acomplish this using references
$current = &$arrayResult;
// get the current level
foreach($arrayKeyOrder as $someKey){
$someValue = $someRow[$someKey];
if(isset($current[$someValue])){
$current = &$current[$someValue];
}else{
$current[$someValue] = array();
$current = &$current[$someValue];
}
unset($someRow[$someKey]);
}
$current = $someRow;
}
return $arrayResult;
}
function unZip($arrayRows, $arrayKeyOrder, $arrayValues = array(), $depth = 0){
$arrayResults = array();
if($depth < count($arrayKeyOrder)){
foreach($arrayRows as $key => $value){
$arrayValues[$depth] = $key;
$arrayResults[] = unZip($value, $arrayKeyOrder, $arrayValues, $depth + 1);
}
}else{
$extra = array_combine($arrayKeyOrder, $arrayValues);
$result = array_merge($extra, $arrayRows);
return $result;
}
if($depth == 0){
for($i = 1; $i < count($arrayKeyOrder); $i++){
$arrayResults = call_user_func_array('array_merge', $arrayResults);
}
}
return $arrayResults;
}
And finally, here is the output. let me know if this is what you were asking for and if it worked OK on a larger data-set.
/vhost/virtual/sandbox/public/index.php:54
array(4) {
[0] = array(4) {
[site_id] = string(1) "0"
[language_id] = string(1) "1"
[name] = string(8) "sitename"
[description] = string(9) "site desc"
}
[1] = array(4) {
[site_id] = string(1) "0"
[language_id] = string(1) "2"
[name] = string(8) "sitename"
[description] = string(9) "site desc"
}
[2] = array(4) {
[site_id] = string(1) "1"
[language_id] = string(1) "1"
[name] = string(8) "sitename"
[description] = string(9) "site desc"
}
[3] = array(4) {
[site_id] = string(1) "2"
[language_id] = string(1) "1"
[name] = string(8) "sitename"
[description] = string(9) "site desc"
}
}
/vhost/virtual/sandbox/public/index.php:55
array(3) {
[0] = array(2) {
[1] = array(2) {
[name] = string(8) "sitename"
[description] = string(9) "site desc"
}
[2] = array(2) {
[name] = string(8) "sitename"
[description] = string(9) "site desc"
}
}
[1] = array(1) {
[1] = array(2) {
[name] = string(8) "sitename"
[description] = string(9) "site desc"
}
}
[2] = array(1) {
[1] = array(2) {
[name] = string(8) "sitename"
[description] = string(9) "site desc"
}
}
}
/vhost/virtual/sandbox/public/index.php:56
array(4) {
[0] = array(4) {
[site_id] = int(1) 0
[language_id] = int(1) 1
[name] = string(8) "sitename"
[description] = string(9) "site desc"
}
[1] = array(4) {
[site_id] = int(1) 0
[language_id] = int(1) 2
[name] = string(8) "sitename"
[description] = string(9) "site desc"
}
[2] = array(4) {
[site_id] = int(1) 1
[language_id] = int(1) 1
[name] = string(8) "sitename"
[description] = string(9) "site desc"
}
[3] = array(4) {
[site_id] = int(1) 2
[language_id] = int(1) 1
[name] = string(8) "sitename"
[description] = string(9) "site desc"
}
}
Try this:
// initialize your array
$all_rows = array();
// loop through query results
while( $row = $qry->fetch_assoc() )
{
// temporarily store these vars for easy use later
$s_id = $row['site_id'];
$l_id = $row['language_id'];
// create an empty array based on site_id and language_id
$all_rows[ $s_id ][ $l_id ] = array();
// loop through all columns returned from query
foreach ( $row as $key => $val )
{
// if it's not one of the two primary keys, push it to the array
if ( ! in_array($key, $all_primary_keys) )
{
$all_rows[ $s_id ][ $l_id ][ $key ] = $val;
}
}
}
Is there a reason the below wouldn't work?
$results = array();
while($row = $qry->fetch_assoc()){
$results[$row['site_id']][$row['language_id']] = array(
'name' => $row['name'],
'description' => $row['description']
);
}
Here are two simple functions to solve your problem. I don't put any example as I have used your data and the same function name and arguments.
The first one takes profit of pointers to solve the first step of the problem:
function nestByKeyNames($rows, $aKeys) {
$tab=Array();
foreach ($rows as &$v) {
// calculate the pointer position
$t=&$tab;
foreach ($aKeys as $v1) {
$t=&$t[$v[$v1]];
unset($v[$v1]);
}
// save the value
$t=$v;
}
return $tab;
}
This one uses a recursive algorithm and give the reverse output
function unNestByKeyNames($arrayRows, $aKeys){
$t=Array();
if (!count($aKeys)) return Array($arrayRows);
foreach ($arrayRows as $k=>&$v) {
$res=unNestByKeyNames($v, array_slice($aKeys,1));
foreach ($res as $k1=>$v1) $t[]=array_merge(Array($aKeys[0]=>$k), $v1);
}
return $t;
}
I have no suggestion about your SQL INSERT approach as long as you take care of sql injection, which I suppose might be the reason of your comment "validation has been removed for clarity"
There is no real method to what you wanting if you want to use the primary key you have to know the column name of the primary key hell you should not the columns your querying for. the best way to do it would be to use the AS keyword in the MySQL Query
SELECT primary as ID, ... where primary is the column name of your primary key and now ID is your primary key in the result set.
You can then just do the standard
$sortedResults = array();
while($row = $queryResult->fetch_assoc()){
$rowId = $row["ID"];
$sortedResults[$rowId] = $row;
}
If you don't know what the primary key is there i no reasonable way to obtain it there is a method to get the table columns and then you could go though them find the primary key save it then you have the primary key to do your while on but this would be one hell of an overhead on every query you make.

php ziparchive renamed file is empty

I'm using php to create a ziparchive which contains some images. This works fine exept when i try to rename the files. This is the code that works:
$zip_archive->open(tempnam("tmp", "zip"), ZipArchive::OVERWRITE);
foreach ($images as $image) {
$path = $image['path'];
$title = $image['title'];
if(file_exists($path)){
$zip_file->addFile($path, pathinfo($path, PATHINFO_BASENAME));
}
}
$zip_archive->close();
$images is an array and could look like this:
$images = array(
'path' => array(
'folder/title1.jpg',
'folder/title2.jpg'
),
'title' => array(
'new_name1.jpg',
'new_name2.jpg'
)
)
I would like to name the image as its title.
$zip_file->addFile($path, $title);
But whats happening is that the files in the zip with the title as name are empty. What am I doing wrong?
If I run this
$images = array(
'path' => array(
'folder/title1.jpg',
'folder/title2.jpg'
),
'title' => array(
'new_name1.jpg',
'new_name2.jpg'
)
);
$i = 0;
foreach($images as $image)
var_dump($image, $i++);
I get
array(2) {
[0]=>
string(17) "folder/title1.jpg"
[1]=>
string(17) "folder/title2.jpg"
}
int(0)
array(2) {
[0]=>
string(13) "new_name1.jpg"
[1]=>
string(13) "new_name2.jpg"
}
int(1)
This means that these
$path = $image['path'];
$title = $image['title'];
are both NULL
You have two ways to fix this:
Change the array to look like
$images = array(
[0] => array(
'path' => 'folder/title1.jpg',
'title' => 'new_name1.jpg'
),
[1] => array(
'path' => 'folder/title2.jpg'
'title' => 'new_name2.jpg',
)
);
in this case your initial code should work
Change the way to access the array, doing something like
for($i = 0;$i < count($images['path']);$i++)
{
$path = $image['path'][$i];
$title = $image['title'][$i];
}
This way you are sure that path and title of the image will have the same index, but it's not recommanded to do so because the array must be ordered.
I suggest you to change the array, your code should be ok that way

Reading PHP array using key value

I have an array that I'm creating inside my PHP script, the var_dump function gives me this value :var_dump($arrayOfValues);
array(3) {
[0]=> array(2) {
[0]=> string(12) "BusinessName"
[1]=> string(13) "ITCompany"
}
[1]=> array(2) {
[0]=> string(7) "Address"
[1]=> string(58) "29 xxxxxx,Canada"
}
[2]=> array(2) {
[0]=> string(20) "PrimaryBusinessPhone"
[1]=> string(14) "(444) 111-1111"
}
[3]=> array(2) {
[0]=> string(13) "BusinessEmail"
[1]=> string(24) "xx#example.com"
}
}
I would like to access to the value of the "BusinessName" using key and not index so if I put : echo $arrayOfValue[0][1]; it gives me the BusinessName that is ITCompany but if I put
: echo $arrayOfValue['BusinessName'][1]; it gives nothing so how can I fix that please?
The array is initialized $arrayOfValue = array(); and then populated dynamically inside a for loop like that
$arrayOfValue[] = array($Label, $Value);
your array has this kind of data
$arrayOfPostsValue[] = array("BusinessName","ITCompany");
$arrayOfPostsValue[] = array("Address","29 xxxxxx,Canada");
$arrayOfPostsValue[] = array("PrimaryBusinessPhone","(444) 111-1111");
$arrayOfPostsValue[] = array("BusinessEmail","xx#example.com");
there is no array key in data So, you have to recreate your desire array
$newArrayOfPostsValue = array();
foreach ( $arrayOfPostsValue as $value ){
$newArrayOfPostsValue[$value[0]] = $value[1];
}
print_r($newArrayOfPostsValue);
and here is output
Array
(
[BusinessName] => ITCompany
[Address] => 29 xxxxxx,Canada
[PrimaryBusinessPhone] => (444) 111-1111
[BusinessEmail] => xx#example.com
)
As mentioned in the comment, change the structure of the array, it will be much easier to handle
$my_array = array(
array('Business Name' => 'It Company'),
array('Address' => 'My address')
);
Looking at the content of your array, I will restructure it as
$my_improved_array = array(
'BusinessName' => 'It Company',
'Address' => 'My Address',
);
This is how you can access,
echo $my_array[0]['BusinessName'] //prints 'It Company'
echo $my_array[1]['Address'] //prints 'My Address'
echo $my_improved_array['BusinessName'] // prints 'It Company'
Try like this and save array as key value pairs and then access the key:
foreach($arrayOfValues as $a)
$arr[$a[0]] = $a[1];
echo $arr['BusinessName'];
While creating that array build it with index as BusinessName
array (
0 => array(
'BusinessName'=> "ITCompany"
)
1 => array(1) (
'Address'=> "29 xxxxxx,Canada"
)
)
etc..
PHP Array example
$array = array();
$array['BusinessName'] = 'ITCompany';
$array['Address'] = '29 xxxxxx,Canada';
And so on... Now you can echo values with
echo $array['BusinessName'];
Also this works
$array = array('BusinessName' => 'ITCompany', 'Address' => '29 xxxxxx,Canada');
First of all, how are you building this array ? Maybe you can directly make a workable array.
Anyway, you can do something like this :
$oldArray = Array(
Array("BusinessName", "ITCompany"),
Array("Address", "29 xxxxxx,Canada"),
Array("PrimaryBusinessPhone", "(444) 111-1111"),
Array("BusinessEmail", "xx#example.com")
);
$newArray = Array();
foreach($oldArray as value) {
$newValue[$value[0]] = $value[1];
}
/* Now, it's equal to
$newArray = Array(
"BusinessName" => "ITCompany",
"Address" => "29 xxxxxx,Canada",
"PrimaryBusinessPhone" => "(444) 111-1111",
"BusinessEmail" => "xx#example.com"
);
*/

Categories