How to remove extra array values - php

I have a php script does this:
Put UPC into form
Submit form
Check to see if the UPC already exists in my database
If yes, fetch it from MySQL database
If not, fetch it from an external server, add it to MySQL database for future use
Display results
It works fine, but I'd like the variable to look exactly the same wether it comes from the MySQL cache, or the external server.
When I print it from the server, it looks like this:
Output:
[upc] => 066721020215
[pendingUpdates] => 0
[status] => success
[ean] => 0066721020215
[issuerCountryCode] => us
[found] => 1
[description] => Christie - Original Ritz Crackers
[message] => Database entry found
[size] => 225 g
[issuerCountry] => United States
[noCacheAfterUTC] => 2012-08-06T12:23:58
[lastModifiedUTC] => 2009-04-06T01:51:08
However, When I print the array from MySQL, it looks like this:
$result = mysql_query("SELECT * FROM UPC WHERE `upc` = '$codes[0]'");
$data = mysql_fetch_array($result);
echo "<pre>" . print_r($data, true) . "</pre>";
Output:
[0] => 066721020215
[upc] => 066721020215
[1] => 0
[pendingUpdates] => 0
[2] => success
[status] => success
[3] => 0066721020215
[ean] => 0066721020215
[4] => us
[issuerCountryCode] => us
[5] => 1
[found] => 1
[6] => Christie - Original Ritz Crackers
[description] => Christie - Original Ritz Crackers
[7] => Database entry found
[message] => Database entry found
[8] => 225 g
[size] => 225 g
[9] => United States
[issuerCountry] => United States
[10] => 2012-08-06
[noCacheAfterUTC] => 2012-08-06
[11] => 2009-04-06
[lastModifiedUTC] => 2009-04-06
I realize it's more or less a cosmetic difference (and an array twice as big as it needs to be), but how would I go about easily removing the 0,1,2,3,etc identifiers without looping through the array creating and manually creating a new one? Is there a function that would remove the numbered identifiers?

You need to use mysql_fetch_array($result, MYSQL_ASSOC) or mysql_fetch_assoc($result).
See http://php.net/manual/en/function.mysql-fetch-array.php and http://www.php.net/manual/en/function.mysql-fetch-assoc.php for more details.
Note that both are discouraged, as they have been replaced by the new(ish) mysqli functions: http://uk.php.net/manual/en/book.mysqli.php

Change the line:
$data = mysql_fetch_array($result);
to:
$data = mysql_fetch_assoc($result);
mysql_fetch_assoc returns the data from the db as an associative array - mysql_fetch_array returns a mixed array, with both numeric and associative indexes.
See http://php.net/manual/en/function.mysql-fetch-assoc.php

Related

PHP array in array in array $_POST

I have a question about displaying a variable that is in the an array of another array. Below is an example of a var_dump() of my $_POST variable. As you can see I have an array.. and another array in that array.. and another array in that array.. I actually need a variable from each of the layers.
Array(
[type] => note
[date_time] => 17-01-01
[initiated_from] => admin
[initiated_by] => admin
[list] => 0
[note] => THIS IS A TEST
[contact] => Array
(
[id] => 250
[email] => TEST#TESTING.COM
[first_name] => TEST
[last_name] => McTESTER
[phone] => (777)777-7777
[ip] => 0.0.0.0
[tags] => buyer, requote, followup1, delete
[fields] => Array
(
[3] => TESTER#TESTER.com
[5] => TESTING TESTER
[10] => STATE
[11] => CITY
[12] => COUNTY
[6] => PHONE NUMBER
[8] => www.test.com
[9] => MORE TESTS
)
Here is my code that I tried.
$sql_note="INSERT INTO customer_notes(customer_email,note,added_by,note_date) VALUES('$_POST[contact][email]','$_POST[note]','$_POST[contact][fields][3]','$note_date')";
(Ignore the $note_date) So these are the three things I am trying to get..
$_POST[note]
$_POST[contact][email]
$_POST[contact][fields][3]
I get the first one just fine but I get ARRAY[EMAIL] and ARRAY[FIELDS][3]
You are using variable expansion incorrectly:
$foo = array();
$foo['one']['two'] = 'OK';
echo "Value is $foo[one][two]\n"; // Value is Array[two]
echo "Value is {$foo[one][two]}\n"; // Value is OK
... and in the wrong job. Your query should look like this:
$sql_note = "INSERT INTO customer_notes(customer_email, note, added_by, note_date)
VALUES (?, ?, ?, ?)";
... and values should be passed in an array. Injecting raw untrusted data into SQL code is terribly messy to write and leads to SQL injection vulnerabilities. Please check the documentation for your database library.

Why data retrieved from database was added to php array two times?

I have a simple user table with columns: username, password, email, name, surname, birthdate, address and city. the first three are mandatory but the rest of them can be null.
I am connecting to the database and fetch rows in an array and print it.
$dbc=mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
$sql = "select * from user";
$data = mysqli_query($dbc, $sql) or die("query exec error");
//$json = array();
if(mysqli_num_rows($data)){
while($row=mysqli_fetch_array($data)){
//$json['Kullanici'][]=$row;
print_r($row);
echo "<br /><br />";
}
}
mysqli_close($dbc);
//echo json_encode($json);
But the output is like this:
Array ( [0] => ayse [username] => ayse [1] => b1b3773a05c0ed0176787a4f1574ff0075f7521e [password] => b1b3773a05c0ed0176787a4f1574ff0075f7521e [2] => ayse#hotmail.com [email] => ayse#hotmail.com [3] => [name] => [4] => [surname] => [5] => 0000-00-00 [birthdate] => 0000-00-00 [6] => [address] => [7] => istanbul [city] => istanbul )
Array ( [0] => baris [username] => baris [1] => 7c4a8d09ca3762af61e59520943dc26494f8941b [password] => 7c4a8d09ca3762af61e59520943dc26494f8941b [2] => bakkurt#hotmail.com [email] => bakkurt#hotmail.com [3] => Barış [name] => Barış [4] => [surname] => [5] => 0000-00-00 [birthdate] => 0000-00-00 [6] => [address] => [7] => [city] => )
The question is why there is both [0]=>baris and [username] => baris. I was expecting only the username=>baris. Was I wrong? Where am i missing?
If i solve this problem, I will convert the array to json by removing comments.
It's not a problem, if you look at the PHP documentation for the mysqli_fetch_array() function, it accepts a parameter resulttype; it determines whether to return records as arrays with numeric indices alone, associative indices alone or both (which is what you have).
By default, the function uses MYSQLI_BOTH.
To get as numeric indices alone:
while($row=mysqli_fetch_array($data, MYSQLI_NUM)){
//this will always return with numeric indices alone
}
For more information check here PHP mysqli_fetch_array
if you need only username => baris
Try mysqli_fetch_assoc.
Courtesy - http://www.php.net
It returns an associative array of strings representing the fetched row
in the result set, where each key in the array represents the name of
one of the result set's columns or NULL if there are no more rows in
resultset.
I think what you are looking for is the resulttype parameter. Have a look at this page: mysqli_result::fetch_array
You probably want to call the fetch_array function like this:
mysqli_fetch_array($data, MYSQLI_ASSOC)
Try using mysqli_fetch_assoc() instead of mysqli_fetch_array().
mysqli_fetch_array() fetch data as both enumerated and associative, so if you only need associative array use mysqli_fetch_array().
You can also read the documentation if you want to know something more about it.

PDO fetchAll() primary key as array group key

I want to store the contents of a specific database into an array, grouped by their primary keys. (Instead of the useless way PDO fetchAll() organises them).
My current code:
$DownloadsPDO = $database->dbh->prepare("SELECT * FROM `downloads`");
$DownloadsArray = $DownloadsPDO->execute();
$DownloadsArray = $DownloadsPDO->fetchAll();
Which then outputs:
Array ( [0] => Array ( [id] => 0 [0] => 0 [path] => /xx-xx/testfile.zip [1] => /xx-xx/testfile.zip [name] => Test Script [2] => Test Script [status] => 1 [3] => 1 ) [1] => Array ( [id] => 1 [0] => 1 [path] => /xx-xx/test--file.zip [1] => /xxxx/testfile.zip [name] => New Script-UPDATE [2] => New Script-UPDATE [status] => 1 [3] => 1 ) )
I was considering to use PDO::FETCH_PAIR, however I will be very soon expanding the amount of data I want to be able to use on this script. This works currently, but when I start to expand the amount of downloads and more clients come into play, obviously the way the data is grouped causes an issue.
Is it possible for me to group each array by their primary key (which is id)?
You can just use
$results = array_map('reset', $stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC))
PDO::FETCH_GROUP|PDO::FETCH_ASSOC returns an array of arrays. The first column is used as the key, and then within key is an array of all the results for that key. However, in our scenario each key will only contain 1 row. reset() returns the first element in array, thus eliminating 1 level of nesting.
This should yield what you are looking for :
$results = $pdos->fetchAll(\PDO::FETCH_UNIQUE|\PDO::FETCH_ASSOC);
I decided to just loop through the results with fetch() and enter them into an array as I go along, this is the code I have used and it works just fine:
$DownloadsPDO = $database->dbh->query("SELECT * FROM `downloads`");
$Array = array();
while ($d = $DownloadsPDO->fetch()) {
$Array[$d['id']]["id"] = $d['id'];
$Array[$d['id']]["name"] = $d['name'];
$Array[$d['id']]["path"] = $d['path'];
}
// Outputs
Array ( [1] => Array ( [id] => 1 [name] => Test Script [path] => /xxxx/testfile.zip ) [2] => Array ( [id] => 2 [name] => New Script-UPDATE [path] => /xxxx/testfile.zip ) )
Which uses the primary key (being id) as the name for the array key, and then adds the data into it.
Thought I would add this as the answer as this solved it, thanks to the guys that helped out and I hope this is helpful to anyone else hoping to achieve the same thing.
I'd like to point out the only solution that works for me:
fetchAll(\PDO::FETCH_GROUP|\PDO::FETCH_UNIQUE|\PDO::FETCH_ASSOC);
Beware that this will strip the first column from the resultset. So the query must be:
SELECT id_keyname AS arrkey, id_keyname, .... FROM ...
I'm still suggesting you to loop using fetch() method. Otherwise, you can use array_reduce() to iterate over the array. A sample on codepad is here.
The code(in human readable form) will be:
$myFinalArray = array_reduce($myInputArray, function($returnArray, $temp) {
$temp2 = $temp['id'];
unset($temp['id']);
$returnArray[$temp2] = $temp;
return $returnArray;
}
);
So, my question is; is it possible for me to group each array by their
primary key (which is id)
Off course, you have 2 options here: Either to change the query or parse a result-set.
So, I'm sure you don't want to change query itself, so I'd go with parsing result-set.
Note:
You should use prepared SQL statements when they make sense. If you want to bind some parameters then its OKAY. But in this case, you only want get get result-set, so prepare() and fetch() will be kinda overdo.
So, you have:
Array ( [0] => Array ( [id] => 0 [0] => 0 [path] => /xx-xx/testfile.zip [1] => /xx-xx/testfile.zip [name] => Test Script [2] => Test Script [status] => 1 [3] => 1 ) [1] => Array ( [id] => 1 [0] => 1 [path] => /xx-xx/test--file.zip [1] => /xxxx/testfile.zip [name] => New Script-UPDATE [2] => New Script-UPDATE [status] => 1 [3] => 1 ) )
And you want:
Array( [id] => Array('bar' => 'foo') ....)
Well, you can do something like this:
$stmt = $database->dbh->query("SELECT * FROM `downloads`");
$result = array();
foreach($stmt as $array){
$result[$array['id']] = $array;
}
print_r($result); // Outputs: Array(Array('id' => Array(...)))

Only one row returned in mysql data retrieval

Firstly, sorry about the long question... but this is doing my head in. Any help would be greatfully accepted.
I've written the following function to return data from a mysql database:
function injuryTable()
{
# get all players that are injured and their injuires...
$sql = "SELECT players.id, players.injury_id, players.pname, injuries_date.name, start_date, end_date
FROM players INNER JOIN injuries_date
ON injury_id = injuries_date.id";
$result = sqlQuery($sql);
return $result;
}
The sqlQuery function is as follows:
function sqlQuery($sql)
{
$products = array();
$link = dbConnect('localhost', 'root', '', 'umarrr');
$result = mysqli_query($link, $sql);
while ($row = mysqli_fetch_array($result))
{
$products[] = $row;
}
# return each row:
return $products;
#mysqli_close($link);
}
It's all connected to the database, and everything works fine.
However when I try to iterate through the results: it only returns one row:
$injury_table = injuryTable();
// make it more readable:
foreach ($injury_table as $table);
{
echo $table['pname'];
echo $table['name'];
echo $table['start_date'];
echo $table['end_date'];
}
The sql statement I wrote above works perfectly in mysql query browser, so does anyone know what the problem here might be?
Output of print_r($injury_table)
Array ( [0] => Array ( [0] => 1 [id] => 1 [1] => 6 [injury_id] => 6 [2] => person [pname] => person [3] => wrist [name] => wrist [4] => 2008-11-21 [start_date] => 2008-11-21 [5] => 2010-11-11 [end_date] => 2010-11-11 ) [1] => Array ( [0] => 2 [id] => 2 [1] => 5 [injury_id] => 5 [2] => woman [pname] => woman [3] => neck [name] => neck [4] => 2009-11-12 [start_date] => 2009-11-12 [5] => 2010-09-09 [end_date] => 2010-09-09 ) [2] => Array ( [0] => 3 [id] => 3 [1] => 4 [injury_id] => 4 [2] => girl [pname] => girl [3] => groin [name] => groin [4] => 2010-11-27 [start_date] => 2010-11-27 [5] => 2010-12-01 [end_date] => 2010-12-01 ) [3] => Array ( [0] => 4 [id] => 4 [1] => 1 [injury_id] => 1 [2] => boy [pname] => boy [3] => achilles [name] => achilles [4] => 2010-02-01 [start_date] => 2010-02-01 [5] => 2010-03-23 [end_date] => 2010-03-23 ) [4] => Array ( [0] => 5 [id] => 5 [1] => 2 [injury_id] => 2 [2] => man [pname] => man [3] => toe [name] => toe [4] => 2010-01-01 [start_date] => 2010-01-01 [5] => 2010-02-02 [end_date] => 2010-02-02 ) )
Some things to check:
Check the return value of mysqli_query(). You assume the query succeeds, and there's far too many reasons for a query to fail to NOT check each time. It will return boolean FALSE on failure.
If you're doing many queries in your script, you'll be opening a new connection handle for each. By default these will NOT be persistent connections, so any transactions you may start will be automatically rolled back after the query results are consumed. Generally it's better to connect to the database ONCE (you can store the handle in a static variable inside your sqlQUery() function if you'd like and reuse it. There aren't many situations where you'd want (or need) multiple handles at the same time, or a brand new sparkling clean handle each time.
Have you tried doing a print_r()/var_dump() of the rows as they're retrieved in the while() loop? Tried spitting out a mysqli_num_rows() to see how many the PHP version of the query is returning?
Are you viewing the results in a browser? Perhaps something in the first or second result rows has an HTML tag (or something that your browser's interpreting) as an HTML tag and is "hiding" the output. View the page's source to make sure they're really not being output, and not just being hidden.
And finally, on the security front, it is very poor practice to allow a web-facing application to connect to the database as 'root'. Any flaws in your code will leave the DB server wide open for anyone to play in. Create an account with the least amount of privileges necessary to get the job done (probably insert/update/select/delete only) and use that instead of the root account. Even if you're just playing around with this on a private server, it's a good habit to get into.
Why are you opening a new connection to the database for each call? This is a very inefficient way of executing queries. I would pass the database connection as a parameter, or since you are using mysqli, just pass the $link as a parameter.
As to why your code is not working, I do not know, but you can try some basic error reporting with the following:
$result = mysqli_query($link, $sql) or
trigger_error('Query Failed: ' . mysqli_error($link));
I would also add the MYSQL_ASSOC to the fetching function, as you are not using the index-based array, this will make your script that much more efficient.
Hope this helps you out.
Really bad (and maybe insulting) answer...
foreach ($injury_table as $table);
{
echo $table['pname'];
echo $table['name'];
echo $table['start_date'];
echo $table['end_date'];
echo '<br/>'; // HTML new line
}
Or
foreach ($injury_table as $table);
{
echo $table['pname'];
echo $table['name'];
echo $table['start_date'];
echo $table['end_date'];
echo "\n"; // Console new line
}

php - replace array elements with another array's elements?

Not sure how to go about this...
But, I have two arrays, one with updated information, another with outdated information... There are a lot more elements in the second array, but I'm looking to "update" the outdated one with the updated information.
Here's what the arrays look like:
//Outdated
Array (
[0] => Array
(
[anum] => 3236468462
[cid] => 4899097762
[mid] => 1104881401
[na_title] =>
[na_fname] => JOHN
[m_initial] =>
[na_lname] => DOE
[na_suffix] =>
[na_addr1] => 1234 SAMPLE AVENUE
[na_addr2] =>
[na_city] => NORWALK
[state] => OH
[zip] =>
[zip_plus_4] =>
[route] => R002
[dma_code] => 510334
)
)
//Updated
Array (
[1] => Array
(
[0] => YUD990
[1] => 98
[2] => 1234 Sample Avenue
[3] =>
[4] => Norwalk
[5] => OH
[6] => 44857-9215
[7] => 3236468462
)
)
To clarify, I want to:
(1) Match up the value for [7] from the updated array with the value for [anum] in the outdated array, and then update [na_addr1], [na_addr2], [na_city], [state], [zip], [zip_plus_4] in the outdated array with the values for [2],[3],[4],[5],[6] (I know I'll need to split the updated [6] in order to get it to map corrected to the outdated)
Feel like I'm making this very confusing... sorry about that...
Your updated array needs to have matching keys, otherwise there's no way to know how the values should replace the old ones. Then the standard array merge works.
$new = array_merge($outdated, $updated);
Assuming that the structure of the update array will never change, you could just use the code below. (I'm assuming that 'zip' is the first 5 digits and zip_plus_4 is the last 4 digits, but I'm not clear exactly what they're supposed to be.)
$old_array['anum'] = $new_array[7];
$old_array['na_addr1'] = $new_array[2];
$old_array['na_addr2'] = $new_array[2];
$old_array['na_city'] = $new_array[3];
$old_array['state'] = $new_array[4];
$zip_code = explode('-', $new_array[6]);
$old_array['zip'] = $zip_code[0];
$old_array['zip_plus_4'] = $zip_code[1];
I'm not sure why the second array doesn't use its own set of matching keys. It would be more readable and help keeps things consistent. For example, if you end up adding another field, some of the elements could be offset by one, which would just cause headaches. But if the arrays used the same keys, you could use the code below and everything would be fine.
$old_array['anum'] = $new_array['anum'];
$old_array['na_addr1'] = $new_array['na_addr1'];
(etc)

Categories