PHP Associative Array Strucuture - php

Is there any thing wrong with this array?
$selects = array(
"getmoney1" => $money["Dimes"],
"getmoney2" => $money["Nickels"],
"getmoney3" => $money["Quarters"]
);
I am learning, and I want to know more, and how to do it right.

There is nothing wrong with this declaration. However it does assume the existence of an array named $money, and that $money["Dimes"], etc. are all set.

Syntactically nothing wrong, but what on earth would the point of it be?
The original array $money would be easier to work with, I suspect.
But I agree with the commenter above - not enough information to go on.

Related

Incorrectly used array_multisort() giving correct result?

I'm currently touching some legacy code in an attempt to clean it and have come across something of a puzzle. It's not even remotely mission critical that I resolve it, so consider this a sporting question at most, but it's still perplexing me. Colour me curious.
This code:
// dummy data for the sake of testing / abstract visualisation;
// x is thrown in as an experiment:
$workTables = array(
array('x' => 5, 'Name' => 'foo3', 'Update_time' => '2013-04-04 04:40',),
array('x' => 4, 'Name' => 'foo4', 'Update_time' => '2013-04-01 04:40',),
array('x' => 3, 'Name' => 'foo2', 'Update_time' => '2013-04-04 09:40',),
array('x' => 2, 'Name' => 'foo1', 'Update_time' => '2013-04-12 04:40',),
array('x' => 1, 'Name' => 'foo5', 'Update_time' => '2012-12-04 04:40',),
);
// original legacy code:
if (!empty($workTables)) {
$sort = array();
foreach ($workTables as $key => $value) {
$sort[$key]["Update_time"] = $value["Update_time"];
}
array_multisort($workTables, SORT_ASC, SORT_STRING, $sort);
}
...while throwing twelve notices ("Notice: Array to string conversion ..."), works as expected, by ordering all elements in $workTables according to Update_time.
(The 'x' column is part of my attempt to rule out that it has anything to do with Name, which in the original code is a fixed prefix followed by a timestamp (e.g. work_table_1367940392, work_table_1367940395, ...), making sorting by Name equivalent to sorting by Update_time.)
Obviously, since I don't want to program by coincidence, at the very least this is going to be replaced with:
// new code:
if (!empty($workTables)) {
$sort = array();
foreach ($workTables as $key => $value) {
$sort[$key] = $value["Update_time"];
}
array_multisort($sort, SORT_ASC, SORT_STRING, $workTables);
}
...which conforms to the description of array_multisort(), also does what we want, and doesn't throw Notices in our face.
But what I'm really interested in is why the old code works (notices notwithstanding).
A partial reason seems to be the behaviour of asort() and co., which have the (partly) undocumented feature that they can work with multi-dimensional arrays by acting according to the contents of the array, working through the structure from "left to right" (at least in PHP 5.4.7 (cli))... but... I'm stuck trying to comprehend what's making $workTables and $sort 'interchangable'.
I've tried to look at PHP's C source code to figure it out, but I'm stuck at trying to understand what happens here:
/* Do the actual sort magic - bada-bim, bada-boom. */
zend_qsort(indirect, array_size, sizeof(Bucket **), php_multisort_compare TSRMLS_CC);
...since my knowledge of C has rusted terribly and zend_qsort() itself is just flatly out of my league.
Any takers?
Keep in mind I'm not desperate for an answer, so don't sink too much time into this, but maybe someone else likes a puzzle, too? :)
Personally, I've invested some time into this purely because I prefer understanding code thoroughly, especially when I'm trying to clean it up - even if it's code that works only by coincidence. I've just reached a dead-end when it comes to further comprehension, so stackoverflow seemed like the best chance for further enlightenment.
So, if you have an idea about what's going on behind the scenes (I suspect it's something trivial I've overlooked; that tends to be my problem after going around in circles for a while), I'd love to hear it! :)
From what I understand, an array is being created and stored in $sort[$key]. Then, once you call array_multisort(), it happens to convert the array back into a string and sort using that string as the value that defines the order -- just as the warning says. Then, this string is used as the order-defining value.
How is this conversion array->string performed? Just doing echo $anArrayValueHere; is not helpful; it prints out Array. Similar trick, echo "" . $anArrayValueHere . ""; also doesn't yield anything useful. (But neither does it yield a notice!)
It's quite possible that serialize() is used. Presuming that, let's see what would get used as a order-defining value:
#!/usr/bin/php5
<?php
$sort[0]["Update_time"] = '2012-12-04 04:40';
echo serialize($sort[0]);
then
$ ./php tmp.php
a:1:{s:11:"Update_time";s:16:"2012-12-04 04:40";}
It looks like the key would be sufficiently definitive to yield something usable to define sort order just as well as just the Update_time value would.
I'm not sure that serialize() is used, but if it is, I think this is the explanation.

Php regexp get the strings from array print_r like string

Im trying to list out here how to match strings that looks like array printr.
variable_data[0][var_name]
I would like to get from above example 3 strings, variable_data, 0 and var_name.
That above example is saved in DB so i same structure of array could be recreated but im stuck. Also a if case should look up IF the string (as above) is in that structure, otherwise no preg_match is needed.
Note: i dont want to serialize that array since the array 'may' contain some characters that might break it when unserializing and i also need that value in the array to be fully visible.
Any one with regexp skills who might know the approach ?
Solution:
(\b([\w]*[\w]).\b([\w]*[\w]).+(\b[\w]*[\w]))
Thos 2 first indexes should be skipped... but i still get what i want :)
Not for nothing but couldn't you just do..
$result = explode('[', someString);
foreach ($result as $i => $v) {
$temp = str_replace(']'. ''. $result[$i]);
//Do something with temp
}
Obviously you need to edit the above a little bit depending on what you are doing but it is very simple and even gives you the same flexibility and you don't need to invoke the matching engine...
I don't think we build regex's here for people... instead please see http://regexpal.com/ for a Regex tester / builder with visual aid.
Furthermore people usually don't know how to use them properly which is then fostered by others creating the expressions for them.
Please remember complex expressions can have terrible performance overheads although there is nothing seemingly complex about your request...
Then after it is compelte post your completed RegEx and answer your own question for maximum 1337ne$$ :)
But since I am nice here is your reward:
\[.+\]\[\d+\]
or
[a-z]+_[a-z]+\[.+\]\[\d+\]
Depending on what you want to match out of the string (which you didn't specify) so I assumed all
Both perform as follows:
arr_var[name][0]; //Matched
arr_var[name]; //Not matched
arr_var[name][0][1];//Matched
arr_var[name][2220][11];//Matched
Again, test them and understand with visual aid at the above link.
Solution:
(\b([\w]*[\w]).\b([\w]*[\w]).+(\b[\w]*[\w]))
Those 2 first indexes should be skipped... but i still get what i want :)
Edit
Here is improved one:
$str = "variable[group1][parent][child][grandchild]";
preg_match_all('/(\b([\w]*[\w]))/', $str,$matches);
echo '<pre>';
print_r($matches);
echo '</pre>';
// Output
Array
(
[0] => variable
[1] => group1
[2] => parent
[3] => child
[4] => grandchild
)

How do I stop MySQL from duplicating every column's entry in returned arrays?

My MySQL queries are returning arrays with duplicate entries: numbered keys and labeled keys with the same data inside. This may be standard, but it seems like a waste, and something that could cause problems if I'm printing values. I mean, not a huge problem, obviously. But I'm just curious if I can stop that. It seems unnecessary. For example:
Array(
[0] => "Ted",
[first_name] => "Ted",
[1] => "Schmidlap",
[last_name] => "Schmidlap"
)
And so on.
I'm pretty new to a lot of this, so this may be a simple question, but Googling doesn't seem to have any answers for me. Anyone know the reason this happens? I'm using PHP's PDO now, but I was doing it straight through the MySQL functions before and the same thing was happening, so I assume it's a byproduct of MySQL interaction.
I can iterate through and unset the numeric ones, because I don't need them, but they're not really in the way right now, so that's just an extra step. Still, is there a way to simply not have them fetched in the first place?
Presumably this is happening after you use mysql_fetch_array (or similar).
You need to add in a flag to specify what array type you want returned or PHP assumes both.
i.e. mysql_fetch_array($result_set, MYSQL_ASSOC|MYSQL_NUM|MYSQL_BOTH)
That depends on the function you are using.
Some functions return both types, others return only one of them.
If you are using PDOStatement->fetch, notice the optional $fetch_style argument it takes.
Your issue is with the mysql_fetch_array function.
If you want only the numbers, use:
$row = mysql_fetch_array($result, MYSQL_NUM)
If you want only the text indexes, use:
$row = mysql_fetch_array($result, MYSQL_ASSOC)
I usually use MySQLi but for PDO you can find more information here: http://us3.php.net/manual/en/pdostatement.fetch.php
Which seems to mean that you should be using this for text indexes:
$row = $statement->fetch(PDO::FETCH_ASSOC);
And this for numeric indexes:
$row = $statement->fetch(PDO::FETCH_NUM);
Also, just to note this since it isn't listed here, if you want an associative array, you can use mysql_fetch_assoc(), or if you want an enumerated (numbered) array use mysql_fetch_row() instead of mysql_fetch_array(). I use this mostly because without it I would often forget the flag, so I got into the habit of just using the specific function.

drupal---the taxonomy array

when i print "print_r($node)" in the node.tpl.php. i get this.
taxonomy] => Array (
[1] => stdClass object (
[tid] =>1
[vid]=>1
[name]=>cms
............)
)
so from the above, I know the taxonomy is an array. the array's value is an object. That the question comes. I looked up the php manual again and again, didn't find there is a saying "the array's value can be a object" why,I can't follow the above's code well. Hope someone can explain it to me. Thank you.
What Pekka write:
echo $node["taxonomy"][1]->tid;
Is not wrong, in the sense that it works for the above example. However, since you are doing this in the node.tpl.php you probably want something more robust, than this, since it only works for nodes with the term that has id 1.
Since the array of taxonomy terms is of the format:
array(tid => term_object)
You need to know the tid to access the term object. If you however want the tid, you can just get the array key:
$tids = array_keys($node["taxonomy"]);
Now, you don't know if or how many terms there is associated to your node, as it can be changed via settings, if you did:
if (!empty($node["taxonomy"])) {
$tids = array_keys($node["taxonomy"]);
$tid = tids[0];
}
You would get the tid of the first term (the one with the lowest tid). If you know from your setup that the node can only have 1 term and since the theme you're doing this in is site specific, this will be good enough for you. Else $tids will be an array of all the tids for the node that you use for your wishes.
in other words, in php, the array's value can be anything. am i right.
Yes, an array can hold values of any data type.
how the code i should write
The "path" to access the variable you show above would be:
echo $node["taxonomy"][1]->tid;

Unique variables inside foreach()

Trying to create a variable with unique name for each $item.
To prevent error "Only variables can be passed by reference".
If there are 5 items in array $items, we should get 5 unique variables:
$item_name_1;
$item_name_2;
$item_name_3;
$item_name_4;
$item_name_5;
All of them should be empty.
What is a true solution for this?
You can dynamically create variable names doing the following:
$item_name_{$count} = $whatever;
I must warn you though, this is absolutely bad style and I've never seen a good reason to use this. In almost every use case an array would be the better solution.
Well, I guess that you can use $item_name_{$count} = "lorem ipsum"; for it
... But won't be better to use an array?
I'm not sure I understand what you want to do, so this may be completely wrong. Anyway, if what you want is an array with empty values you can use this code:
<?php
$arr = array_fill(0, 3, '');
var_export($arr) // array ( 0 => '', 1 => '', 2 => '', 3 => '', )
?>
See array_fill for more information.
If this is the wrong answer, please clarify what you mean. I may be able to help you.

Categories