How to specify integers as keys in an associative array? - php

I have some code that grabs some rows from a table and I want to make an associative array in PHP that will be like [row_id] => row_title. This will then be used to populate a select list. The problem is, the key, unless I include a string in it, always reverts to an ordered number starting with 0. If I add a string in with the key, then the key retains the ID that I want. But obviously I don't want the string in the key.
Here's my code:
public static function select_array(){
$courses = ORM::factory('course')->order_by('title')->find_all();
$out = array();
foreach($courses as $c){
$out[$c->id] = $c->title;
}
return $out;
}
The $c->id should be the id from the database, but PHP is overriding this with a count number. If I do this:
public static function select_array(){
$courses = ORM::factory('course')->order_by('title')->find_all();
$out = array();
foreach($courses as $c){
$test = "." . $c->id;
$out[$test] = $c->title;
}
return $out;
}
Then the key will include the correct ID, but with a "." in front... I've tried using (string)$c->id but no luck with that either. I've also tried setting $test as " " . $c->id and then trimming it, but that doesn't work, and it's just a weird hacky attempt anyway.
Hope that makes sense. My question: How to simply tell the key to be a specific number?

Can you var_dump $courses before the foreach statement and $out before the return?

Well if it's overwriting it, I don't see why. Try this...
foreach($courses as $c){
$test = "" . $c->id;
$out[(int)$test] = $c->title;
}

The first snippet looks like it should work the way you want. Assuming that $c->id doesn't produce an ordered list of ints, are you sorting the array after retrieving from select_array()? Have you tried var_dump()'ng $out after the foreach and before the return statement?
If converting to a string solves the problem, try something like
$out[(string)$c->id] = $c->title;

Related

Variable Variables for Array Key

Currently I am attempting to call a multidimensional array, using a string as a key or keys. I would like to use the following code, but I think the key is being interpreted as a string. Any solution?
$data= [];
$data['volvo'] = "nice whip";
$test = "['volvo']";
$data['drivers']['mike'] = "decent";
$test2 = "['drivers']['mike']";
echo $data$test; // should read 'nice whip'
echo $data$test2; // should read 'decent'
You just use the variable (which should just be the string and not PHP syntax) in place of the string literal.
$cars = [];
$cars['volvo'] = 'nice whip';
$test = 'volvo';
echo $cars[$test];
If you need a dynamic array access solution, you could also write a function, which does the actual array access like this:
function path($array, $path) {
$path = is_array($path) ? $path : explode('.', $path);
$current = $array;
while (count($path)) {
$seg = array_shift($path);
if (!isset($current[$seg])) throw new Exception('Invalid path segment: ' . $seg);
$current = $current[$seg];
}
return $current;
}
In your case, this would look like this
echo path($data, 'volvo');
echo path($data, 'drivers.mike');
or
echo path($data, ['volvo']);
echo path($data, ['drivers', 'mike']);
The problem is you can't pass multiple levels in one string like that. (If so, PHP would have to start looking for code fragments inside string array keys. And how would it know whether to interpret them as fragments and then split the string key up, or keep treating it as one string??)
Alt 1
One solution is to change the structure of $data, and make it a single level array. Then you supply keys for all the levels needed to find your data, joined together as a string. You would of course need to find a separator that works in your case. If the keys are plain strings then something simple like underscore should work just fine. Also, this wouldn't change the structure of your database, just the way data is stored.
function getDbItem($keys) {
// Use this to get the "old version" of the key back. (I.e it's the same data)
$joinedKey = "['".implode("'],['", $keys)."']";
$joinedKey = implode('_', $keys);
return $data[$joinedKey];
}
// Example
$data = [
'volvo' => 'nice whip',
'drivers_mike' => 'decent'
];
var_dump(getDbItem(['drivers', 'mike'])); // string(6) "decent"
Alt 2
Another way is to not change number of levels in $data, but simply traverse it using the keys passed in:
$tgt = $data;
foreach($keys as $key) {
if (array_key_exists($key, $tgt)) {
$tgt = $tgt[$key];
}
else {
// Non existing key. Handle properly.
}
}
// Example
$keys = ['drivers', 'mike'];
// run the above code
var_dump($tgt); // string(6) "decent"

for loop and appending to an array in PHP

I have the following code:
$items = array();
foreach($following as $storeOwner)
{
array_push($items, $productRepository->mostRecentItem($storeOwner->getId(), 5));
}
I am trying to append the results of
$productRepository->mostRecentItem($storeOwner->getId(), 5)
to $items. How do I do so? Why doesn't the above code work?
Try this:
$items = array();
foreach($following as $storeOwner)
{
$items[] = $productRepository->mostRecentItem($storeOwner->getId(), 5);
}
Also, take a look to the result of the mostRecentItem Method... .
var_dump you different objects and return values to make sure that contain what you think they should contain. The code looks "correct" so it's probably the objects and values that are not.

Accessing an array in an object

If i knew the correct terms to search these would be easy to google this but im not sure on the terminology.
I have an API that returns a big object. There is one particular one i access via:
$bug->fields->customfield_10205[0]->name;
//result is johndoe#gmail.com
There is numerous values and i can access them by changing it from 0 to 1 and so on
But i want to loop through the array (maybe thats not the correct term) and get all the emails in there and add it to a string like this:
implode(',', $array);
//This is private code so not worried too much about escaping
Would have thought i just do something like:
echo implode(',', $bug->fields->customfield_10205->name);
Also tried
echo implode(',', $bug->fields->customfield_10205);
And
echo implode(',', $bug->fields->customfield_10205[]->name);
The output im looking for is:
'johndoe#gmail.com,marydoe#gmail.com,patdoe#gmail.com'
Where am i going wrong and i apologize in advance for the silly question, this is probably so newbie
You need an iteration, such as
# an array to store all the name attribute
$names = array();
foreach ($bug->fields->customfield_10205 as $idx=>$obj)
{
$names[] = $obj->name;
}
# then format it to whatever format your like
$str_names = implode(',', $names);
PS: You should look for attribute email instead of name, however, I just follow your code
use this code ,and loop through the array.
$arr = array();
for($i = 0; $i < count($bug->fields->customfield_10205); $i++)
{
$arr[] = $bug->fields->customfield_10205[$i]->name;
}
$arr = implode(','$arr);
This is not possible in PHP without using an additional loop and a temporary list:
$names = array();
foreach($bug->fields->customfield_10205 as $v)
{
$names[] = $v->name;
}
implode(',', $names);
You can use array_map function like this
function map($item)
{
return $item->fields->customfield_10205[0]->name;
}
implode(',', array_map("map", $bugs)); // the $bugs is the original array

How can I convert an array of strings to an array of integers?

I'm getting this error with my current PHP code:
Notice: TO id was not an integer: 1, 2. 1) APNS::queueMessage ->
How can I convert to an array of strings to an array of integers like in this other question: ID not integer... EasyAPNS ?
I'm basically trying to pass ids (from my database,) to newMessage() like this Apple example:
// SEND MESSAGE TO MORE THAN ONE USER
// $apns->newMessage(array(1,3,4,5,8,15,16));
// ($destination contain a string with the Ids like "1,2,3")
Here is my code below:
if (isset($destination))
{
//$destination = 1,2,..
$dest = explode(",", $destination);
if (isset($time))
{
$apns->newMessage($dest, $time);
}
else
{
$apns->newMessage($dest);
}
$apns->addMessageAlert($message);
$apns->addMessageBadge($badge);
$apns->addMessageSound('bingbong.aiff');
$apns->queueMessage();
header("location:$url/index.php?success=1");
}
I would create a wrapper function that accepts an array, and then call it.
function newMessageArray($array) {
foreach ($array as $element) {
$apns->newMessage($element);
}
}
This way, you can call newMessageArray() with an array of integers, such as array(1,2,3,4,5), and they will all be sent.
Also, you should change the variable names (from $array and $element) to something more meaningful. I don't know what you're trying to do, so I wasn't sure what names to use.
Your Question is not clear, It's only a guess work.
It seems to be error in convert integer, try
$dest = explode(",", $destination);
$destArray = array();
foreach($dest as $key => $val) {
$destArray[$key] = intval($val);
}
if (isset($time))
{
$apns->newMessage($destArray, $time);
}
else
{
$apns->newMessage($destArray);
}
Convert where the string is not integer using 'intval'.
I believe what you may be looking for is how to do this:
You have ids in your database table, right? And you are trying to get multiple ids into an array so that the array can be used in $apns->newMessage() call, right? (I checked the source for this...) But, the ids are somehow coming over as strings instead of ints.
So, you probably want to just make sure that the new array is made up of ints, like this:
function to_int($x) {
return (int)$x;
}
$dest = array_map("to_int", $dest);
There are probably other ways to do this, but this way, you at least know that you have int variables in that array. Hope that helps!

Make 1d Array from 1st member of each value in 2d Array | PHP

How can you do this? My code seen here doesn't work
for($i=0;i<count($cond);$i++){
$cond[$i] = $cond[$i][0];
}
It can be as simple as this:
$array = array_map('reset', $array);
There could be problems if the source array isn't numerically index. Try this instead:
$destinationArray = array();
for ($sourceArray as $key=>$value) {
$destinationArray[] = $value[0]; //you may want to use a different index than '0'
}
// Make sure you have your first array initialised here!
$array2 = array();
foreach ($array AS $item)
{
$array2[] = $item[0];
}
Assuming you want to have the same variable name afterwards, you can re-assign the new array back to the old one.
$array = $array2;
unset($array2); // Not needed, but helps with keeping memory down
Also, you might be able to, dependant on what is in the array, do something like.
$array = array_merge(array_values($array));
As previously stated, your code will not work properly in various situation.
Try to initialize your array with this values:
$cond = array(5=>array('4','3'),9=>array('3','4'));
A solution, to me better readable also is the following code:
//explain what to do to every single line of the 2d array
function reduceRowToFirstItem($x) { return $x[0]; }
// apply the trasnformation to the array
$a=array_map('reduceRowTofirstItem',$cond);
You can read the reference for array map for a thorough explanation.
You can opt also for a slight variation using array_walk (it operate on the array "in place"). Note that the function doesn't return a value and that his parameter is passed by reference.
function reduceToFirstItem(&$x) { $x=$x[0]; }
array_walk($cond, 'reduceToFirstItem');
That should work. Why does it not work? what error message do you get?
This is the code I would use:
$inArr;//This is the 2D array
$outArr = array();
for($i=0;$i<count($inArr);$i++){
$outArr[$i] = $inArr[$i][0];
}

Categories