Background: I am pulling in XML objects from a public IMDB-for-TV API. My goal is to pull certain values out of those objects -- like, say, a list of every episode title, put into an array so that I can do what I want with it.
Problem: Although I can write code that does execute exactly the way I want it, it spits out errors as it does so, so I know something's wrong with the way I iterate over my objects... but I can't figure out a better way. I'd really love some advice.
So first off, here's a look at the object I'm dealing with.
SimpleXMLElement Object
(
[Episodelist] => SimpleXMLElement Object
(
[Season] => Array
(
[0] => SimpleXMLElement Object
(
[episode] => Array
(
[0] => SimpleXMLElement Object
(
[epnum] => 1
[seasonnum] => 01
[prodnum] => 101
[airdate] => 1989-07-05
[link] => http://www.tvrage.com/Seinfeld/episodes/305788
[title] => Good News, Bad News
)
[1] => SimpleXMLElement Object
(
[epnum] => 2
[seasonnum] => 02
[prodnum] => 103
[airdate] => 1990-05-31
[link] => http://www.tvrage.com/Seinfeld/episodes/150618
[title] => The Stakeout
)
The show is an object containing an object "episode list", which contains object "season x", which contains object "episode y", which contains the value I'm after -- "title". So for each episode, I want to grab $this->list->Season[X]->episode[Y]->title.
Here is the function I wrote to do this. It takes two arguments: the season number, and the episode number.
public function showEpisode($s,$e) {
$s = $s - 1; // To compensate for zero-indexing.
$e = $e - 1;
if (!empty($this->list->Season[$s]) && !empty($this->list->Season[$s]->episode[$e])) {
return $this->list->Season[$s]->episode[$e]->title;
} else {
return 0;
}
}
I know there's something wrong with how it's written.
Anyway, here's my code for actually working with it.
$season = 1;
$episode = 1;
$errors = 0;
while ($errors < 2) {
if ($xfiles->showEpisode($season,$episode)!= 0) {
echo $xfiles->showEpisode($season,$episode) . "<br />";
$episode++;
$errors = 0;
} else {
$errors++;
$season++;
$episode = 1;
}
}
My logic is:
Start at Season 1, Episode 1.
Echo the title of the current episode.
If that fails, increment the error-counter by one, and go up a season by incrementing $season++ and putting the $episode counter back at 1.
If you get two errors in a row, it means going up a season failed, because we've hit the end of the show, so the loop ends.
Desired result: A neat, simple list of every episode title.
Actual result: A blank page, using this code; nothing is ever returned. When I used my last version of the function, which I have very stupidly deleted and cannot seem to recreate, I did echo a full set of episodes exactly as I wanted -- but after each season, and three times at the end of the file, I got "Trying to get property of non-object" errors, because of the calls to non-existent episodes.
Question: What is the correct, practical way to loop through a large object like this? What conditions should I use in my showEpisode function to check if the result will exist or not?
Thanks a ton to anyone who can help, I've done my best and Googled a lot but I'm just baffled.
This looks like a job for a foreach-loop.
foreach ($xfiles->list->Season as $season) {
foreach ($season->episode as $episode) {
echo $episode->title . "<br />";
}
}
Alternatively (or should I say ideally), put this inside a method of the list object and replace $xfiles with $this.
Related
$q = $_POST['q'];
$inCart = isset($_COOKIE['cart']) ? unserialize($_COOKIE['cart']) : array();
function alreadyInCart() {
global $inCart, $good, $q;
foreach ($inCart as $inCart1) {
if ($inCart1[0] == $good->id) { // if this good already in cart
$inCart1[1] = $inCart1[1] + $q; // write sum of q's to existing array
return true; // and return true
}
}
return false; // return false if not
}
if (alreadyInCart() == false) { // if good added to cart for the first time
$inCart[] = array($good->id, $q); // add array at the end of array
}
Hello. So my problem is that I'm running a function to find out if $good->id is already inside of 2d $inCart array.
$inCart looks something like this:
Array
(
[0] => Array
(
[0] => 6
[1] => 1
)
[1] => Array
(
[0] => 5
[1] => 1
)
)
Where [0] is a good ID and [1] is an amount of this good in a cart.
So I tracked that function actually does what I want and returns true/false as expected, but looks like it only does it inside of itself. Cause if I put print_r($inCart1[1]) inside of a function it does add up and outputs the sum, as expected. But when I output the array at the end of the code (outside the function) the amount doesn't add up, just stays how it was before the function run.
Any ideas why that happens?
Ok, in case someone faces the same problem: found a solution.
Or should I say found a mistake?
The problem was with the foreach ($inCart as $inCart1). Must be replaced with foreach ($inCart as &$inCart1) in order to change array values in a loop. The other way, it just reads values, bit can't change them.
I'll note that this is a very special case, hence the question to begin with. Under normal circumstances, such a function would be simple:
I have an array named $post_id, which contains 5 values
(Each numerical)
In order to print each value in the array, I use the following loop:
.
for ($i = 0; $i < $num; $i++)
{
echo $post_id[$i] . ' ';
}
...Which prints the following: 49, 48, 47, 46, 43
3. In my database, I have a table that looks like this:
post_categories
_____________________
post_id | category
__________|__________
43 | puppies
43 | trucks
46 | sports
46 | rio
46 | dolphins
49 | fifa
4. So, using the data in the array $post_id, I'd like to loop a database query to retrieve each value in the category column from the post_categories table, and place them into uniquely named arrays based on the "post id", so that something like...
echo $post_id_49[0] . ' ', $post_id_46[1];
...Would print "fifa rio", assuming you use the above table.
An example of such a query:
//Note - This is "false" markup, you'll find out why below
for ($i = 0; $i < $num; $i++)
{
$query = "SELECT category FROM post_categories WHERE post_id = $post_id[$i]";
fakeMarkup_executeQuery($query);
}
Why is this a "special" case? For the same reason the above query is "false".
To elaborate, I'm working inside of a software package that doesn't allow for "normal" queries so to say, it uses it's own query markup so that the same code can work with multiple database types, leaving it up to the user to specify their database type which leaves the program to interpret the query according to the type of database. It does, however, allow the query to be stored in the same "form" that all queries are, like "$result = *query here*" (With the only difference being that it executes itself).
For that reason, functions such as mysql_fetch_array (Or any MySQL/MySQLi function akin to that) cannot, and will not work. The software does not provide any form of built in alternatives either, effectively leaving the user to invent their own methods to achieve the same results. I know, pretty lame.
So, this is where I'm stuck. As you'd expect, all and any information you find on the Internet assumes you can use these MySQL & MySQLi functions. What I need, is an alternative method to grab one array from the results of a looped query per loop. I simply cannot come to any conclusion that actually works.
tl;dr I need to be able to (1) loop a query, (2) get the output from each loop as it's own array with it's own name, and (3), do so without the use of functions like mysql_fetch_array. The query itself does not actually matter, so don't focus on that. I know what do with the query.
I understand this is horrifically confusing, long, and complicated. I've been trudging through this mess for days - Close to the point of "cheating" and storing the data I'm trying to get here as raw code in the database. Bad practice, but sure as heck a lot easier on my aching mind.
I salute any brave soul who attempts to unravel this mess, good luck. If this is genuinely impossible, let me know so that I can send the software devs an angry letter. All I can guess is that they never considered that a case like mine would come up. Maybe this is much more simple then I make it to be, but regardless, I personally cannot come to an logical conclusion.
Additional note: I had to rewrite this twice due to some un explained error eliminating it. For the sake of my own sanity, I'm going to take a break after posting, so I may not be able to answer any follow up questions right away. Refer to the tl;dr for the simplest explanation of my need.
Sure you can do this , here ( assuming $post_ids is an array of post_id that you stated you had in the OP ), can I then assume that I could get category in a similar array with a similar query?
I don't see why you couldn't simply do this.
$post_id = array(49, 48, 47, 46, 43);
$result = array();
foreach($post_id as $id)
{
//without knowing the data returned i cant write exact code, what is returned?
$query = "SELECT category FROM post_categories WHERE post_id = $id";
$cats = fakeMarkup_executeQuery($query);
if(!empty($cats)) {
if(!isset($result[$id])){
$result[$id] = array();
}
foreach( $cats as $cat ){
$result[$id][] => $cat;
}
}
}
Output should be.
Array
(
[49] => Array
(
[0] => fifa
)
[46] => Array
(
[0] => sports
[1] => rio
[2] => dolphins
)
[43] => Array
(
[0] => puppies
[1] => trucks
)
)
Ok, assuming you can run a function (we'll call it find select) that accepts your query / ID and returns an array (list of rows) of associative arrays of column names to values (row), try this...
$post_categories = [];
foreach ($post_id as $id) {
$rows = select("SOME QUERY WHERE post_id = $id");
/*
for example, for $id = 46
$rows = [
['category' => 'sports'],
['category' => 'rio'],
['category' => 'dolphins']
];
*/
if ($rows) { // check for empty / no records found
$post_categories[$id] = array_map(function($row) {
return $row['category'];
}, $rows);
}
}
This will result in something like the following array...
Array
(
[49] => Array
(
[0] => fifa
)
[46] => Array
(
[0] => sports
[1] => rio
[2] => dolphins
)
[43] => Array
(
[0] => puppies
[1] => trucks
)
)
I would first like to thank you for taking the time to look at my question--I am quite novice at PHP/CodeIgniter programming, however, I enjoy it very much.
What I am trying to do:
1) Retrieve each CompanyId associated with the company when the user is logged in. I achieve this by passing the $CompanyId (in my controller) from the session as a parameter to a query in my model. I have this working well as such:
// Assign query result to array to be used in view
$data['campaigns'] = $this->model_record->retrieve_campaign($CompanyId);
2) The return value is an array nested as such:
Array (
[campaigns] => Array (
[0] => Array (
[CampaignId] => 1
[DID] => 2394434444
[FWDDID] => 3214822821
[ProductId] => 1
[CampaignName] => Fort Myers Bus #1
[ProductName] => CallTrack - Sharktek
[Active] => 1
[CompanyId] => 1 )
)
3) Once this is processed, I am trying to create a for each loop that queries each CampaignId through another query in my model. Due to the MVC pattern I am implementing, I have to pass the results of this query to my $data array to send to the view.
foreach($data['campaigns'] as $campaign) {
$ids[] = $campaign['CampaignId'];
}
foreach ($ids as $row) {
$data['ids'] = $this->model_record->week_data(0,$row, $StartDate);
}
4) I am then trying to test view all the results of my queries in my view, however, I am only receiving one value, but when I echo the results of the foreach of the CampaignIds, it they all show up. Does anyone have any suggestions?
<?php
foreach($ids as $row):
echo $ids['MyCount'];
endforeach
?>
5 Extra) I have not begun to approach this yet, but once I get this working, I would like to run the query week_data 7 times as it is returning the data for each day of the week. My assumption is that I would place a for loop until it hits 7, is this correct?
Thank you again, for attempting to help me--I greatly appreciate the work many of you put into this community.
This line:
$data['ids'] = $this->model_record->week_data(0,$row, $StartDate);
Should look like:
$data['ids'][] = $this->model_record->week_data(0,$row, $StartDate);
As it is, the first line overwrites $data['ids'] until all you're left with is the last one. You need to add them to an array to collect all of them.
I'm new to PHP and I'm trying to modify my Wordpress-based Learning Management theme (called Academy on ThemeForest) to be able to work out which lesson in the current course the user is up to.
In other words, I want to run a check to see which lessons the user has completed, getting only the ID of the first lesson in the course hierarchy that has not been completed.
Here's everything I know:
Within the loop of a single post (in this case a "course"), this is how I get the array of the current course's lessons:
<?php $lessons_array = ThemexCourse::sortLessons(ThemexCourse::$data['course']['lessons']); ?>
This produces this nested array:
Array ( [0] => WP_Post Object ([ID] => 117 [menu_order]=>1) [1] => WP_Post Object ([ID] => 124 [menu_order]=>2) [2] => WP_Post Object ([ID] => 156 [menu_order]=>3))
I've truncated it a bit since the two values, [ID] and [menu_order], are the most important: they tell you the ID of each lesson and their hierarchy in the course.
But this is where I get stuck: I don't want to get all of the lesson IDs, just the one the user has yet to complete.
In order to check if a user has completed a lesson or not, I've been using this:
<?php if(ThemexCourse::isCompletedLesson($lesson_ID)) { echo 'Completed'; } ?>
So using the above information, is it possible to return a single ID of only the next incomplete lesson?
Thanks to anyone in advance for your help!
I think that should do it:
$next_lesson = NULL;
foreach($lessons_array as $index=>$lesson) {
if(!ThemexCourse::isCompletedLesson($lesson->ID)) {
$next_lesson = $lesson;
break;
}
}
echo "Next lesson is: " . $next_lesson->ID;
I access an API that returns an array of elements.
If there is only one element, it will return the array as:
Array {
[response] => Array {
[name] => Frank
}
}
However, if there are multiple results, it goes one level deeper to account for each result:
Array {
[response] => Array {
[0] = > Array {
[name] => Frank
}
[1] = > Array {
[name] => John
}
}
}
This is quite frustrating as it means I have to first check if there is just one element or more than one, and then code each one separately.
Is there a better solution that automatically takes care of both scenarios (e.g. one result vs. multiple results) and always retrieves the name's that are available regardless ?
You could either write an iterator that would deal with your special case, or you iterate over it an deal with the special case:
foreach ($array['response'] as $responses)
{
isset ($responses[0]) || $responses = array($responses);
foreach ($repsonses as $response)
{
# standard processing code per each item.
}
}
Special cases can be very annoying, so take care of them early and ideally make them disappear.
(If you can) Tweak the original API to always return the array with the indexed keys even when there are only one item in the array.
Else, add this one after you fetch the result from the API.
if(count($result['response'])==1) { $newResult['response'][0]=$result; }
else { $newResult=$result; }