Get element by index, [n] - php

I'm using PHPQuery to read some content from HTML, I'm unable to get the element by it's index using the square bracket notation.
See this simple example:
$html = '<div><table id="theTable"><tr><td>FIRST TD</td><td>SECOND TD</td><td>THIRD TD</td></tr></table></div>';
$pq = phpQuery::newDocumentHTML($html);
$table = $pq->find('#theTable');
$tds = $table->find('td');
echo "GETTING BY INDEX:\n\n";
echo '$tds[1] = ' . $tds[1];
echo "\n\n\n";
echo "GETTING IN FOREACH:\n\n";
foreach($tds as $key => $td){
echo '$tds[' . $key . '] = ' . pq($td) . "\n";
}
The output of this is:
GETTING BY INDEX:
$tds[1] =
GETTING IN FOREACH:
$tds[0] = FIRST TD
$tds[1] = SECOND TD
$tds[2] = THIRD TD
I would have expected that I can get the contents of $tds[1] using square brackets, but seems not. How can I get it by index?

Try a var_dump($tds), it'll tell you whats exactly inside the tds. Maybe those keys are actually strings and you should use:
echo "GETTING BY INDEX:\n\n";
echo '$tds['1'] = ' . $tds['1'];
Edit: Also, on your foreach you're using pq(), maybe you should use this
echo "GETTING BY INDEX:\n\n";
echo '$tds[1] = ' . pq($tds[1]);

Found the answer just after posting the question. Instead of square brackets you need to use eq(n):
echo '$tds[1] = ' . $tds->eq(1);

Try the following:
echo '$tds[1] = ' . $tds['1'];

Related

Nested foreach when reading XML (in PHP)

I need to create a CRON job that are weekly going to read a XML file. The XML file contains information about all the shows at a range of cinemas.
What I want to do is to read the XML file, extract the information I need about each show, and then upload each show to a database. But I run into trouble when I start nesting the for-loops.
I want each tuple to contain the following information:
Tile | FilmWebNr | Rating | Version | Center | Screen | Date | Time |
The URL for the XML is http://217.144.251.113/static/Shows_FilmWeb.php
Here is a pastebin where I try to list all the dates for each screen per Title.
Here is the result. As you can see, the dates is only displayed when there are more than 1 screen per Title. I dont get why the attributes array isn't always available.
I struggle with getting the last three (screen, date and time).
$map_url = "http://217.144.251.113/static/Shows_FilmWeb.php";
$response_xml_data = file_get_contents($map_url);
$data = simplexml_load_string($response_xml_data);
$array = (array) simplexml_load_string($response_xml_data);
$json = json_encode($array);
$configData = json_decode($json, true);
$movies = $configData['Performances']['Title'];
foreach ($movies as $title) {
echo "Title: " . $title['#attributes']['Name'] . '<br/>';
echo "FilmWebNr: " . $title['FilmWebNum'] . '<br/>';
echo "Rating: " . $title['TitleRating'] . '<br/>';
echo "Version: " . $title['TitleVersion'] . '<br/>';
echo "Center: " . $title['Center']['#attributes']['Name'] . '<br/>';
foreach ($title['Center']['Screen'] as $screen) {
//here I run into trouble
}
}
Let say I try to add the following in the inner loop:
$screen['#attributes']['Name'];
I get an error saying "Undefined index: #attributes".
So sometimes the attributes seems to be in an array, but sometimes not. Even though It is always a part of the XML.
Rather than going from XML-JSON-Arrays, it may be better to learn how to work with SimpleXML and you will find it's quite easy.
The main thing is to get used to how the various elements are layered and use foreach loops to iterate over the blocks...
$map_url = "http://217.144.251.113/static/Shows_FilmWeb.php";
$response_xml_data = file_get_contents($map_url);
$data = simplexml_load_string($response_xml_data);
$movies = $data->Performances->Title;
foreach ($movies as $title) {
echo "Title: " . $title['Name'] . '<br/>';
echo "FilmWebNr: " . $title->FilmWebNum . '<br/>';
echo "Rating: " . $title->TitleRating . '<br/>';
echo "Version: " . $title->TitleVersion . '<br/>';
echo "Center: " . $title->Center['Name'] . '<br/>';
foreach ($title->Center->Screen as $screen) {
echo "screen:".$screen['Name']. '<br/>';
foreach ( $screen->Date as $date ) {
echo "Date:".$date['Name']. '<br/>';
foreach ( $date->ShowID as $showID ) {
echo "Time:".$showID->Time. '<br/>';
}
}
}
}

Access object's array property with string

I tried to access an object property which has array form using string variable but not able do so when the string contains index selection. Take a look at this example.. what i was tring to do is to use $access3 like string
$dummy = new stdClass();
$dummy->testNormal = 'itemNormal';
$dummy->testArray = array('item1', 'item2');
$access1 = 'testNormal';
$access2 = 'testArray';
$access3 = 'testArray[0]';
echo 'try access1: ' . $dummy->{$access1} . '<br />';
echo 'try access2: ' . $dummy->{$access2}[0] . '<br />';
echo 'try access3: ' . $dummy->{$access3} . '<br />';
echo 'try direct: ' . $dummy->testArray[0] . '<br />';
The above code will return
try access1: itemNormal
try access2: item1
--- ERROR MESSAGE --
try access3: <-- does not contain anything because of error, my expectation is it will be "item1"
try direct: item1
Is this impossible with php?
$access_handler = explode('[', $access3);
// get array name
$array_name = $access_handler[0];
// get array index
$array_index = substr($access_handler[1], 0, -1);
// call the property
echo $dummy->$array_name[$array_index];
you might create function for this. Otherwise you would have to use eval to evaluate your string, but that is not recommended. Also there are many ways to separate index from array name and then run it as in this example

php echo statement inside $output

I have the following php code:
$skizzar_masonry_item_width = $masonry_item_width;
$skizzar_masonry_item_padding = $masonry_item_padding;
$skizzar_double_width_size = $masonry_item_width*2 +$masonry_item_padding;
$output .= '<style>.skizzar_masonry_entry.skizzar_ma_double, .skizzar_masonry_entry.skizzar_ma_double img {width:'.$skizzar_double_width_size.'}</style>';
return $output;
For some reason though, the value of $skizzar_double_width_size is not being added into the $output - is there a way to echo a value in an output variable?
As #Rizier123 mentioned, ensure you initialise any string variables before trying to append to them.
$var = '';
$var .= 'I appended';
$var .= ' a string!';
I would also like to strongly discourage you from using inline styles as well as generating them with inline PHP. Things get very messy very quickly.
In a situation like this you need to check that all the variables you are using in the calculation are valid before you panic.
So try
echo 'before I use these values they contain<br>';
echo '$masonry_item_width = ' . $masonry_item_width . '<br>';
echo '$masonry_item_padding = ' . $masonry_item_padding . '<br>';
$skizzar_masonry_item_width = $masonry_item_width;
$skizzar_masonry_item_padding = $masonry_item_padding;
$skizzar_double_width_size = $masonry_item_width*2 +$masonry_item_padding;
echo 'after moving the fields to an unnecessary intemediary field<br>';
echo '$skizzar_masonry_item_width = ' . $skizzar_masonry_item_width . '<br>';
echo '$skizzar_masonry_item_padding = ' . $skizzar_masonry_item_padding . '<br>';
echo '$skizzar_double_width_size = ' . $skizzar_double_width_size . '<br>';
$output .= '<style>.skizzar_masonry_entry.skizzar_ma_double, .skizzar_masonry_entry.skizzar_ma_double img {width:'.$skizzar_double_width_size.'}</style>';
echo $output;
This should identify which fields are causing you problems.
Also while testing always run with display_errors = On It saves so much time in the long run.

double quotes inside single quotes in MYSQL result?

I'm trying to do something very basic but I can't figure out how.
basically i'm trying to convert the mysql result ($row) into the following format (literal strings):
"0784562627828" => "James",
"0786636363663" => "David",
I have all the data stored in the database and I can get them echoed on my page like so:
$phone = $row['phone'];
$name = $row['name'];
$list .=''.$phone.'';
echo $list;
could someone please advise on this?
Thanks
Just assign them inside an array like you normally would:
$array = array();
while(your fetch here) {
$array[$row['phone']] = $row['name'];
}
To check its contents, you can use var_dump($array) or print_r($array)
Or just straight up show them, like the one you formatted:
while(your fetch here) {
echo '"' . $row['phone'] . '"' . ' => ' . '"' . $row['name'] . '"' . '<br/>';
}
you mean something like this?
$list = array();
$list[$phone] = $name;
Can you do something like
$list = [];
foreach($rows as $row) {
$list[$row['phone']] = $row['name'];
}

Getting XML with PHP: how to get attributes from 2 nodes with same name

I am getting attributes from XML nodes and saving them to variables with a for loop as such:
for ($i = 0; $i < 10; $i++){
$group = $xml->Competition->Round[0]->Event[$i][Group];
if($group == "MTCH"){
$eventid = $xml->Competition->Round[0]->Event[$i][EventID];
$eventname = $xml->Competition->Round[0]->Event[$i][EventName];
$teamaname = $xml->Competition->Round[0]->Event[$i]->EventSelections[0][EventSelectionName];
$teambname = $xml->Competition->Round[0]->Event[$i]->EventSelections[1][EventSelectionName];
echo "<br/>" . $eventid . ": " . $eventname . ", " . $teamaname . "VS" . $teambname;
}//IF
}//FOR
I can save each Event[EventID] and each Event[EventName] but I cannot get the EventSelections[EventSelectionNames] to save.
I am guessing this is because there are multiple (2) <EventSelection>s for each <Event>, this is why I tried to get them individually uising [0] and [1].
The part of the XML file in question looks like:
<Event EventID="1008782" EventName="Collingwood v Fremantle" Venue="" EventDate="2014-03-14T18:20:00" Group="MTCH">
<Market Type="Head to Head" EachWayPlaces="0">
<EventSelections BetSelectionID="88029974" EventSelectionName="Collingwood">
<Bet Odds="2.10" Line=""/>
</EventSelections>
<EventSelections BetSelectionID="88029975" EventSelectionName="Fremantle">
<Bet Odds="1.70" Line=""/>
</EventSelections>
</Market>
</Event>
Can anyone point me in the right direction to save the EventSelectionNames to variables?
Rather than looping and checking for $group, use xpath to select data directly:
$xml = simplexml_load_string($x); // assume XML in $x
$group = $xml->xpath("/Event[#Group = 'MTCH']")[0];
echo "ID: $group[EventID], name: $group[EventName]" . PHP_EOL;
If there are always two <EventSelections>, you can:
echo "Team A: " . $group->Market->EventSelections[0]['EventSelectionName']" . PHP_EOL;
echo "Team B: " . $group->Market->EventSelections[1]['EventSelectionName']" . PHP_EOL;
Otherwise, use foreach:
foreach ($group->Market->EventSelections as $es)
$teamnames[] = $es['EventSelectionName'];
echo "There are " . count($teamnames) . "Teams:" . PHP_EOL;
foreach ($teamname as $teamname) echo $teamname . PHP_EOL;
see it in action: https://eval.in/105642
Note:
The [0] at the end of the code-line starting with $group = $xml->xpath...requires PHP >= 5.4. If you are on a lower version, update PHP or use:
$group = $xml->xpath("/Event[#Group = 'MTCH']");
$group = $group[0];
Michi's answer is more correct and better coded but I also found the adding the node 'Market' to my code worked as well:
$teamaname = $xml->Competition->Round[0]->Event[$i]->Market->EventSelections[0][EventSelectionName];
$teambname = $xml->Competition->Round[0]->Event[$i]->Market->EventSelections[1][EventSelectionName];

Categories