drupal--why $node->taxonomy is an array - php

someone wrote this code.
foreach ($node->taxonomy as $term) {
$tids[] = 't.tid = %d';
$args[] = $term->tid;
}
how he knows that in foreach "$node->taxonomy" is an array? and when i loop it,
foreach ($node->taxonomy as $term) {
}
the output that i get will be the $term's value. i don't know how it is change into the 't.tid = %d' and $term->tid. thank you.

In Drupal-related code, a $node is almost always an object produced by the node_load() function. Since every module has the opportunity to add its own properties to this object, it's very hard to find a central documentation of these properties.
By experience and by variable inspection, seasoned Drupal developers know that when set $node->taxonomy is always an array of term object (as returned by the taxonomy_get_term() function) indexed by their respective ids (named tids, for Term ID). This array is set by the taxonomy_nodeapi() function when $op == 'load' and is produced by the taxonomy_get_terms() function.
The question give little information but we can guess that the loop is meant to build two arrays used to generate a database query that filter on the tid column matching those of the $node object. Because the terms' data is already stored in the items of $node->taxonomy, let's hope that this query is not used to re-load the terms to display some of their name and/or description. Collecting 't.tid = %d' is probably a bad idea, the query would be better build with a single "tid in (". db_placeholder($args) .")" WHERE clause after collecting all the tids in $args.

The question is very unclear. All Items under the node object are arrays. You can check it yourself bu using:
print_r($node);
die;
Or using any PHP debugger.
for the foreach, It is very simple foreach... I don't understand what is the problem with that.

t.tid is simply an SQL query. %d is a placeholder for $args[], which consists of $term->tid. It's like this structure: PDO connections.

Related

PHP referencing variables in an array as foreach keys

I know my title is quite ambivalent but if you bear me, you'll find it is not so bad :P
I have a class method that gets quite different database fields in any order and builds an array based on those fields (each key adds another level into the array).
Now, that's the easy part. I also have a correction function that unifies the e.g. costs by some demographic data. The problem is that I need to address the right level in the correction formula.
I try to make an example:
I ask fields A,year,B,C,D and my correction formula for D depends on the year and C. I have formalized so that C and D are always the last ones to list but the problem is that how do I address the year so that I could get out an answer like [A][year][B]=function(year,c,d). The fields are in an array ($retr['fields']=array("A","year","B","C") (the result D comes automatically)
I tried to use foreach like
$retr['fields']=array("A","year","B","C")
$temp=get_data($retr);
foreach($temp as $${$retr['fields'][0]} => $yd)
foreach ($yd as $${$retr['fields'][1]} => $cd) {
$output[$${$retr['fields'][0]}][$${$retr['fields'][1]}]=0;
foreach ($cd as $a => $v)
$output[$${$retr['fields'][0]}][$${$retr['fields'][1]}]+=$v*$act[$year][$a]
and so on, but it seems that one can't use a variable variable as a key in foreach (or then I have got the syntax wrong). As now it just says that "Undefined variable: year"
Do you have any ideas how to express what I need?
Well I solved it, or rather not solved but programmed around.
For each foreach I checked the corresponding field and if it was year, I made a variable with value of current foreach key and referenced it with $$variable.
Like this:
$temp=get_data($retr);
foreach($temp as $varA => $yd) {
if ($retr[0]=="year")
$year_var=varA;
.
.
.
$output[$varA][$varB]+=$v*$act[$$year_var][$a]
I still would have preferred a cleaner solution but given my timeframe (or rather the loss of it) this should suffice.
I'm still interested in the "perfect solution"(TM)
Thx anyway :)
It's kind of hard to understand your structure, but it appears you're fetching some data items and then categorize them into tree-like structure.
In this case, even though a particular attribute (e.g. year) appears on some upper level it's still, essentially, an attribute of the data item itself, so keep it as such: convert the "value" into a non-scalar (either object or hash). Then you would be able to work with those attributes without referencing outer loop values (and without resorting to variable variables):
foreach($arr as $subarr) {
foreach ($subarr as $subsubarr) {
// ... and so on
foreach ($lastlevel as $value) {
$adjusted = correctionFunc($value->data, $value->year, $value->somethingelse); // assuming value is an object
}
}
}

How to merge some static data with json encode mysql array data?

I am trying to merge a static data with json encode array data for output. Here is my php code:
$arr = array();
$rs = mysql_query("SELECT id, name, picture, mail, gender, birthday FROM users WHERE id='$logged_id' ");
while($obj = mysql_fetch_object($rs)) {
$arr[] = $obj;
}
echo '{"users":'.json_encode($arr).'}';
Now I want to merge other data with it:
$user_ip = array("user_ip" => $user_ip_address);
I have tried array_merge($arr, $user_ip). But it didn't work. I think this is not correct json array format if I merge with existing data array. Please let me know what to do how to output other data as well as current data coming from mysql with json encode.
I am getting such output with my existing code, which is correct:
{"users":[{"id":"14","name":"Sonu Roy","picture":"image012.jpg","mail":"myemail#gmail.com","gender":"Male","birthday":"1983-01-11"}]}
But now I want to add other variable e.g $user_ip_address as user's data joining with current output data like this:
{"users":[{"id":"14","name":"Sonu Roy","picture":"image012.jpg","mail":"myemail#gmail.com","gender":"Male","birthday":"1983-01-11",user_ip:"127.0.0.1"}]}.
I want to get it in this way. How to do it? Please let me know. Thanks in advance.
try this:
echo json_encode(array('users' => $arr, 'user_ip' => $user_ip_address));
on a side note:
you should use PHP PDO class to connect and query the database.
mysql_fetch_object returns an object, not an array. So, what are you doing by $arr[] = $obj; is just adding an object into an array. So, the actual structure of the $arr is something like
$arr => [
[0] => Object(....),
[1] => Object(....),
....
]
In your particular case, I assume you are fetching single row by primary key, so there are only one object.
THe simpliest way to fix this is to add a field to an object. I haven't worked with PHP since 5.3, so can't be sure, but it's as simple as adding
$obj->user_ip = $user_ip_address;
inside the loop.
Btw, a couple of questions for you:
Why do you use loop if it should result in a single row?
Why you are embedding the variable directly into SQL query. It's quite vulnerable, read about sql-injections and how to prevent it (one day I was really tired telling people here on SO to use PDO and prepared statements, so just go read about it),
Have you read the documentation about mysql_fetch_object and array_merge? Why not (because if you have read it you wouldn't be asking the question).
Tried debugging? E.g. attaching a debugger and watching for variables contents? Inserting logging or (God forgive me) debug print with echo?
"Didn't work" is a quite bad error description. This time you was lucky, because the error was obvious. Next time, please, be more specific.

Mongodb like statement with array

I am trying to save some db action by compiling a looped bit of code with a single query, Before I was simply adding to the the like statements using a loop before firing off the query but i cant get the same idea going in Mongo, id appreciate any ideas....
I am basically trying to do a like, but with the value as an array
('app', replaces 'mongodb' down to my CI setup )
Here's how I was doing it pre mongofication:
foreach ($workids as $workid):
$this->ci->app->or_like('work',$workid) ;
endforeach;
$query = $this->ci->db->get("who_users");
$results = $query->result();
print_r($results);
and this is how I was hoping I could get it to work, but no joy here, that function is only designed to accept strings
$query = $this->ci->app->like('work',$workids,'.',TRUE,TRUE)->get("who_users");
print_r($query);
If anyone can think of a way any cunning methods I can get my returned array with a single call again it would be great I've not found any documentation on this sort of query, The only way i can think of is to loop over the query and push it into a new results array.... but that is really gonna hurt if my app scales up.
Are you using codeigniter-mongodb-library? Based on the existing or_like() documentation, it looks like CI wraps each match with % wildcards. The equivalent query in Mongo would be a series of regex matches in an $or clause:
db.who_users.find({
$or: [
{ work: /.*workIdA.*/ },
{ work: /.*workIdB.*/ },
...
]});
Unfortunately, this is going to be quite inefficient unless (1) the work field is indexed and (2) your regexes are anchored with some constant value (e.g. /^workId.*/). This is described in more detail in Mongo's regex documentation.
Based on your comments to the OP, it looks like you're storing multiple ID's in the work field as a comma-delimited string. To take advantage of Mongo's schema, you should model this as an array of strings. Thereafter, when you query on the work field, Mongo will consider all values in the array (documented discussed here).
db.who_users.find({
work: "workIdA"
});
This query would match a record whose work value was ["workIdA", "workIdB"]. And if we need to search for one of a set of ID's (taking this back to your OR query), we can extend this example with the $in operator:
db.who_users.find({
work: { $in: ["workIdA", "workIdB", ...] }
});
If that meets your needs, be sure to index the work field as well.

PHP scope question

I'm trying to look through an array of records (staff members), in this loop, I call a function which returns another array of records (appointments for each staff member).
foreach($staffmembers as $staffmember)
{
$staffmember['appointments'] = get_staffmember_appointments_for_day($staffmember);
// print_r($staffmember['appointments'] works fine
}
This is working OK, however, later on in the script, I need to loop through the records again, this time making use of the appointment arrays, however they are unavailable.
foreach ($staffmembers as $staffmember)
{
//do some other stuff
//print_r($staffmember['appointments'] no longer does anything
}
Normally, I would perform the function from the first loop, within the second, however this loop is already nested within two others, which would cause the same sql query to be run 168 times.
Can anyone suggest a workaround?
Any advice would be greatly appreciated.
Thanks
foreach iterates over a copy of the array. If you want to change the value, you need to reference it:
foreach($staffmembers as &$staffmember) // <-- note the &
{
$staffmember['appointments'] = get_staffmember_appointments_for_day($staffmember);
// print_r($staffmember['appointments'] works fine
}
From the documentation:
Note: Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself. foreach has some side effects on the array pointer. Don't rely on the array pointer during or after the foreach without resetting it.
and
As of PHP 5, you can easily modify array's elements by preceding $value with &. This will assign reference instead of copying the value.

How do I create a list or an array of objects in PHP?

I'm a .net programmer vb & c#, but I can't seem to figure out how to get my objects into a list or array in PHP.
var mylist = new List<myobject>();
mylist.add(myobject1);
mylist.add(myobject2);
What I have tried.
Products being a property for a collection of orderitems:
$this->Products = getOrderItems();
public function getOrderItems()
{
$items = array();
$count = 0;
// connect to db, query.....
while($row = mysql_fetch_array($result, MYSQL_BOTH)){
$count++;
$items[$count] = ($row);
}
echo 'Count of Order Items...' . $count;
return $items;
}
Am I even close?
$items = array();
while($row = mysql_fetch_array($result, MYSQL_BOTH)) {
$items[] = $row;
}
echo 'Count of Order Items...', count($items);
$this->Products = getOrderItems(); is legal in PHP, but it refers to the (global) function getOrderItems() instead of the class method. class methods and variables always have to be prefixed with $this-> (or self::, if they're static vars) when called from inside the class.
in your sample-code, you have that wrong. getOrderItems is defined as class method, but your call is not $this->-scoped, thus php assumes a function. it should throw an function not found-error.
the [] notation adds an element to the end of an array.
the index of the first element in your sample code is 1 (isn't that the standard case for VB?). php normally starts at 0 - though it's possible (because php-arrays are not real arrays) to start at arbitrary indices i'd recommend to stick with zero.
mysql_fetch_array is an ancient way of working with mysql. nowadays you're better of with mysqli or (even better) PDO.
(...) a list or array in php.
lists, arrays, stacks, whatever: in php everthing is an ordered map (misleadingly called array):
PHP: Arrays: An array in PHP is actually an ordered map. A map is a type that associates values to keys. This type is optimized for several different uses; it can be treated as an array, list (vector), hash table (an implementation of a map), dictionary, collection, stack, queue, and probably more. As array values can be other arrays, trees and multidimensional arrays are also possible.
update:
sorry, i haven't got enough time right now to explain the finer nuances of pdo/mysqli over mysql.
so here are just the basics:
oop: pdo and mysqli are object oriented (tough mysqli got functional aliases)
prep statements: most important: pdo/mysqli got prepared statements. that means, you first prepare the query with placeholders once, then fill in the values later (without the need to prepare the query a second time). this approach has 3 obvious advantages:
performance: it's faster, because the database only has to analyze, compile and optimize the query once (at least with complex queries)
security: no need for quoted strings (happens automatically!), making sql-injection attacks harder
maintainability: the logic and data part of the query are separated, thus easier to read and you don't have to do a lot of string concenation
driver driven: pdo is not database specific. there are several supported db-systems, making it easier to port your code to other db-backends (but it's not an db-abstraction layer like ODBC, so the SQL still has to be compatible) and increasing reusability
of course, there's a lot more to it
What orlandu63 posted is correct - using $items[] = $row means that $row is appended numerically as the next element of $items.
Another option is that if there's an id field in $row, you can do $items[$row->id] = $row;, which has the advantage of indexing your array and making it easier to find a given item.
I really suggest reading through http://www.php.net/manual/en/language.types.array.php, which will explain to you some of the cool things PHP allows with arrays.

Categories