Multisorting a nested array in php - php

I've got a bunch of content pulled out of several databases and compiled into a nested array like this:
Array
(
[0] => Array
(
[id] => 3
[published] => 1433940002
[content] => This is some content
)
[1] => Array
(
[id] => 52
[published] => 1433940001
[content] => This is some more content
)
[2] => Array
(
[id] => 16
[published] => 1433940003
[content] => This is some more content
)
)
Since I cannot sort the content whilst it is retrieved (because it is done using several queries from as many databases) I want to dig down a level into the array and sort by the "published" date whilst maintaining the depth of the array so I end up with...
Array
(
[0] => Array
(
[id] => 52
[published] => 1433940001
[content] => This is some more content
)
[1] => Array
(
[id] => 3
[published] => 1433940002
[content] => This is some content
)
[2] => Array
(
[id] => 16
[published] => 1433940003
[content] => This is some more content
)
)
I'm pretty sure array_multisort() is the way to go but I can't think where to start! Could somebody be so kind as to give me a pointer?

Thanks to #Rizier123's policing of my question I figured it out myself. For anyone else finding this thread here's my solution using the example array I supplied above.
//-- get disorganised content from databases here
usort($array, "publishcmp");
//-- output organised content here
function publishcmp($a , $b){
if ($a['published'] == $b['published']) {
return 0;
}
return ($a['published'] < $b['published']) ? -1 : 1;
}
Pretty much taken verbatim from php.net

Related

Getting out the value of a key in multidimentional array in php

In my php query I got this output:
{"projects":[{"id":127,"name":"efrat","status":{"id":10,"name":"development","label":"development"},"description":"","enabled":true,"view_state":{"id":10,"name":"public","label":"public"},"access_level":{"id":90,"name":"administrator","label":"administrator"},"custom_fields":[{"id":1,"name":"Customer email","type":"email","default_value":"","possible_values":"","valid_regexp":"","length_min":0,"length_max":50,"access_level_r":{"id":10,"name":"viewer","label":"viewer"},"access_level_rw":{"id":10,"name":"viewer","label":"viewer"},"display_report":true,"display_update":true,"display_resolved":true,"display_closed":true,"require_report":false,"require_update":false,"require_resolved":false,"require_closed":false}],"versions":[],"categories":[{"id":93,"name":"Monitor","project":{"id":0,"name":null}},{"id":31,"name":"Proactive","project":{"id":0,"name":null}},{"id":30,"name":"Project","project":{"id":0,"name":null}},{"id":29,"name":"Support","project":{"id":0,"name":null}}]}]}
after using 'json_decode' method on it, I get this:
"(
[projects] => Array
(
[0] => Array
(
[id] => 127
[name] => myprojectname
[status] => Array
(
[id] => 10
[name] => development
[label] => development
)
[description] =>
[enabled] => 1
[view_state] => Array
(
[id] => 10
[name] => public
[label] => public
)
[access_level] => Array
(
[id] => 90
[name] => administrator
[label] => administrator
)
[custom_fields] => Array
(
[0] => Array
(
[id] => 1
[name] => Customer email
[type] => email
[default_value] =>
[possible_values] =>
[valid_regexp] =>
[length_min] => 0
[length_max] => 50
[access_level_r] => Array
(
[id] => 10
[name] => viewer
[label] => viewer
)
[access_level_rw] => Array
(
[id] => 10
[name] => viewer
[label] => viewer
)
[display_report] => 1
[display_update] => 1
[display_resolved] => 1
[display_closed] => 1
[require_report] =>
[require_update] =>
[require_resolved] =>
[require_closed] =>
)
)
[versions] => Array
(
)
[categories] => Array
(
[0] => Array
(
[id] => 93
[name] => Monitor
[project] => Array
(
[id] => 0
[name] =>
)
)
[1] => Array
(
[id] => 31
[name] => Proactive
[project] => Array
(
[id] => 0
[name] =>
)
)
[2] => Array
(
[id] => 30
[name] => Project
[project] => Array
(
[id] => 0
[name] =>
)
)
[3] => Array
(
[id] => 29
[name] => Support
[project] => Array
(
[id] => 0
[name] =>
)
)
)
)
)
)"
In my PHP, how can I release the "name" object value (the result should be 'myprojectname') from this array? I've tried many foreach loops that got me nowhere.
Thank you,
It looks like you have one object, that when decoded actually only has one array item. So, in your case, ‘myprojectname’ may simply be “$projects[0][‘name’]”
If many array items, you could
foreach ($projects as $project) {
echo $project[‘name’];
}
EDIT: I took object provided and json_decoded it myself, it doesn't match the json_decoded item presented by OP -- the first image shows the code to var_dump 'name' OP desired, part of the code also below:
$decoded = json_decode($obj);
$projects = $decoded->projects;
$name = $projects[0]->name;
Your 'projects' contains an array ("projects":[{"id":127, ... }]). I assume that the 'projects'-array might contain multiple 'project'-objects like this?
{
"projects":
[
{
"id":127,
"name":"my-project"
},
{
"id":128,
"name":"my-other-project"
}
]
}
In that case you need the arrow notation to access the name property, for example:
foreach ($projects as $project_object) {
foreach ($project_object as $project) {
echo $project->name . '<br/>';
}
}
EDIT:
I took a minimal code example of the OP and got the expected result:
Can you add more details in your code snippets in your original question or provide us with a working example of your code?
There are some online PHP sandboxes that can help you with this. For example: I stripped out all code that does not seem related to your question and got the result you are looking for in two different ways:
http://sandbox.onlinephpfunctions.com/code/009c53671fd9545e4fcecfe4b0328974381ee2ce
It is also a good idea to sum up all the foreach loops that you already tried, so we can see if you were nearly there with your own solution. This way we can understand your question better and it prevents us from offering solutions that you already used.

How to classify array items?

I have a query which fetches all comments for question and answers in one page (each page is containing at least one post (question), and maybe plus one or more posts (answers)). Now I need to separate comments according to its own question or answers.
The result of my query (fetching all comments) is something like this:
while ($results = $sth->fetch(PDO::FETCH_ASSOC)) {
echo '<pre>';
print_r($results);
}
/* Output:
Array
(
[id] => 1
[post_id] => 1
[content] => Have you any tried so far?
)
Array
(
[id] => 2
[post_id] => 3
[content] => Great answer, upvote
)
Array
(
[id] => 3
[post_id] => 3
[content] => That semicolon is redundant in line 5. Pplease edit it
)
Array
(
[id] => 4
[post_id] => 2
[content] => Won't work ...!
)
Array
(
[id] => 5
[post_id] => 3
[content] => #alex You are right thanks, Edited.
)
So, as you see in the output, all comments are mixed.. Now I need to classify them. Something like this:
/* NewOutput:
[1] => Array
post_id ^ (
[0] => Array
(
[id] => 1
[content] => Have you any tried so far?
)
)
[2] => Array
post_id ^ (
[0] => Array
(
[id] => 4
[content] => Won't work ...!
)
)
[3] => Array
post_id ^ (
[0] => Array
(
[id] => 2
[content] => Great answer, upvote
)
[1] => Array
(
[id] => 3
[content] => That semicolon is redundant in line 5. Pplease edit it
)
[2] => Array
(
[id] => 5
[content] => #alex You are right thanks, Edited.
)
)
Well, Now I want to know, how can I create a nested array according to the value of specific key in the array? exactly like above.
Try this...
$output = array();
foreach($results as $r){
$key = "post_".$r["post_id"];
if(!array_key_exists($key, $output)){
$output[$key] = array();
}
array_push($output[$key], array("id"=>$k["id"], "content"=>$k["content"]));
}
print_r($output);

Replace an array inside a multidimensional array if the key exist

I am trying to build a form where user inputs a data from a string and the form will get subsets of data through json src based on the input and create a multidimensional array and save it in database. If the input was previously added to database, I dont want it to append in the array again.
Here is how my code looks:
//SET UP the Array
$thisquery_themes[] = array(
strtolower($themename) => array(
"author"=>$data['Author'],
"desc"=>$data['Description'],
"screenshot"=> $screenshot,
"link"=> $data['URI'],
"count"=> 1
)
);
//Get Previously saved data
$existing_themes = get_option('top_themes');
if(!empty($existing_themes)){
foreach ($existing_themes as $group){
foreach(array_keys($group) as $key) {
if($group[strtolower($themename)] == strtolower($themename)){
unset($group[$key][strtolower($themename)]);
}
}
}
$total_themes= array_merge($existing_themes , $thisquery_themes);
update_option('top_themes', $total_themes);
} else {
update_option('top_themes', $thisquery_themes);
}
its not. if the key exist in the array, the data is still being added in the array:
Array (
[0] => Array (
[towfiq-i._v5] => Array (
[author] => Towfiq I.
[desc] => Towfiq I. official website.
[count] => 1
)
)
[1] => Array (
[towfiq-i._v5] => Array (
[author] => Towfiq I.
[desc] => Towfiq I. official website.
[count] => 1
)
)
[2] => Array (
[wp-bangla] => Array (
[author] => Ifty Rahman
[desc] => A website template for wpbangla
[count] => 1
)
)
[3] => Array (
[towfiq-i._v5] => Array (
[author] => Towfiq I.
[desc] => Towfiq I. official website.
[count] => 1
)
)
[4] => Array (
[wp-bangla] => Array (
[author] => Ifty Rahman
[desc] => A website template for wpbangla
[count] => 1
)
)
But I want it to be like this(Notice how "count" field value added up. let me know if its possible ):
Array (
[0] => Array (
[towfiq-i._v5] => Array (
[author] => Towfiq I.
[desc] => Towfiq I. official website.
[count] => 3
)
)
[1] => Array (
[wp-bangla] => Array (
[author] => Ifty Rahman
[desc] => A website template for wpbangla
[count] => 2
)
)
Any help would be greatly appreciated. Thanks
Why are you using an array within an array if it's only going to hold one value? Unless that's what's being thrown at you, your structure could easily look like:
Array (
[towfiq-i._v5] => Array (
[author] => Towfiq I.
[desc] => Towfiq I. official website.
[count] => 3
)
[wp-bangla] => Array (
[author] => Ifty Rahman
[desc] => A website template for wpbangla
[count] => 2
)
)
Then your world would become a lot easier because you could check to see if the array element exists by using isset($existing_themes[strtolower($themename)]) (as an example.)
If you can't change how you receive $existing_themes, you can reformat the data like this:
$existing_themes_mod = array();
foreach ($existing_themes as $t) {
$existing_themes_mod[key($t)] = reset($t);
}
This should give you enough of a strategy to work with an be able to run an "update" on existing entries instead of an appendage. If you need help writing it, please show me your attempt first.
EDIT - Thanks for pasting your code. You should watch out for all that whitespace by the way... here's a better way to achieve your goal
if (!empty($existing_themes)) {
if (isset($existing_themes[strtolower($themename)])) {
if (isset($existing_themes[strtolower($themename)]['count'])) {
$existing_themes[strtolower($themename)]['count'] = $existing_themes[strtolower($themename)]['count'] + 1;
} else {
$existing_themes[strtolower($themename)]['count'] = 1;
}
$thisquery_themes = array();
}
$total_themes= array_merge($existing_themes , $thisquery_themes);
update_option('top_themes', $total_themes);
} else {
update_option('top_themes', $thisquery_themes);
}
The reason your attempt didn't work is because when you try to change the $value by incrementing it by 1, it doesn't modify the original array. When you use foreach like that, you need to iterate by reference or else you can't modify the value. You're making too much work for yourself!

Create HTML lists from PHP arrays

I am trying to create various, standard HTML list styles from PHP arrays for a movie database I'm building as part of my final year project at university, however I'm having some trouble accessing/understanding how to do this. I've got the relevant data from the various APIs I'm using, but I'd like to create the entire list dynamically, dropping in the correct bits of information where appropriate.
Details of the two list styles I'm looking to create are below.
List style 1 - Character/Cast details
For the first style of list, I'd like to create it as:
<ul>
<li>Cast name - Character name</li>
<li>Cast name - Character name</li>
<li>etc. etc.</li>
<ul>
My data set direct from the array looks like this:
Array
(
[abridged_cast] => Array
(
[0] => Array
(
[name] => Daniel Craig
[id] => 162687443
[characters] => Array
(
[0] => James Bond
)
)
[1] => Array
(
[name] => Javier Bardem
[id] => 162661456
[characters] => Array
(
[0] => Silva
)
)
[2] => Array
(
[name] => Judi Dench
[id] => 162652435
[characters] => Array
(
[0] => M
)
)
[3] => Array
(
[name] => Ralph Fiennes
[id] => 162653681
[characters] => Array
(
[0] => Gareth Mallory
[1] => Mallory
)
)
[4] => Array
(
[name] => Naomie Harris
[id] => 162705781
[characters] => Array
(
[0] => Eve
)
)
)
In the above example, there's five cast members w/ their respective character names, however on some other examples, there's more or less than five, so, ideally, I'd want the system to know however many cast members were given and create a list for each, up to a maximum of 10 names.
List style 2 - Videos
Similar to the last style, however this list will hopefully look like this:
<ul>
<li><a href='<http://youtube.com/<dynamically generated URL direct to the clip>'><img src='dynamically generated URL to the clip's thumbnail' /></a></li>
<li>same as above...</li>
</ul>
The source array looks like this:
Array
(
[id] => 37724
[youtube] => Array
(
[0] => Array
(
[name] => Trailer
[size] => HQ
[source] => 24mTIE4D9JM
)
[1] => Array
(
[name] => Official Trailer
[size] => HD
[source] => 6kw1UVovByw
)
[2] => Array
(
[name] => Trailer 1
[size] => HD
[source] => 1Uyjf5Pp0Ko
)
[3] => Array
(
[name] => Trailer 2
[size] => HD
[source] => 5Ejo9_3iUpw
)
)
)
Apologies for the length of this post, thanks in advance to anyone who may be able to assist!
The thing you are looking for is called a foreach loop. For your first example it would look something like this:
foreach($dataSet['abridged_cast'] as $castMember){
echo '<li>'.$castMember['name'].'-'.implode(', ', $castMember['characters']). '</li>';
}
Now this example is purely illustratory though it most definetely be the begginers approach.
Still, I would strongly recommend investigating MVC patterns and PHP frameworks, like for example YII. If deployed and configured right YII with all its goodness should make all the repetitive work done for you here.
I've seen that your question contains two parts, though I am not willing to write a sample for the second one, since it is practically the same as the first and with proper attention - you will get on track and figure it out.

getting story tags from graph api returns strange id results for the tagged

The best way for me to explain this is to show you. Seems like a float() error in a 64bit system.
when i call /anotherfeed/feed or any page for that matter, posts with story_tags return some of the id's as a float error.
sample story tag with float error in id. [id] => 1.7153566624E+14
My question is, how do i fix this, or what am i doing wrong? all i am doing is looping in a foreach statement.
if($fvalue[story_tags]){
echo 'Tags: ';
$sTags=$fvalue[story_tags];
foreach ($sTags as $skey=>$svalue){
foreach ($svalue as $gkey=>$hvalue){
$id=$hvalue[id];
echo ''.$hvalue[name].' '.$id.' ';
}
}
}
[story_tags] => Array
(
[0] => Array
(
[0] => Array
(
[id] => 1.7153566624E+14
[name] => Another Feed
[offset] => 0
[length] => 12
[type] => page
)
)
Array
(
[data] => Array
(
[0] => Array
(
[id] => 171535666239724_156133294510726
[from] => Array
(
[name] => Another Feed
[category] => App page
[id] => 171535666239724
)
[story] => Another Feed shared Non-Profits on Facebook's photo.
[story_tags] => Array
(
[0] => Array
(
[0] => Array
(
[id] => 1.7153566624E+14
[name] => Another Feed
[offset] => 0
[length] => 12
[type] => page
)
)
[20] => Array
(
[0] => Array
(
[id] => 41130665917
[name] => Non-Profits on Facebook
[offset] => 20
[length] => 23
[type] => page
)
)
)
[picture] => http://photos-d.ak.fbcdn.net/hphotos-ak-ash3/557037_10150932300320918_1908237167_s.jpg
[link] => http://www.facebook.com/photo.php?fbid=10150932300320918&set=a.85612830917.95996.41130665917&type=1
[name] => Wall Photos
[caption] => Have you heard of the #[159208207468539:274:One Day without Shoes] (ODWS) campaign? ODWS is an annual initiative by #[8416861761:274:TOMS] to bring awareness around the impact a pair of shoes can have on a child's life.
During the 2012 campaign, #[20531316728:274:Facebook] drove 20% of traffic to the ODWS microsite and TOMS even launched a Facebook-exclusive "Barefoot & Blue" giveaway with #[25266987484:274:Essie Nail Polish] for the second year in a row.
We think this is a pretty cool example of creating exclusive content around an important initiative that keeps people engaged and involved!
[properties] => Array
(
[0] => Array
(
[name] => By
[text] => Non-Profits on Facebook
[href] => http://www.facebook.com/nonprofits
)
)
[icon] => http://static.ak.fbcdn.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif
[type] => photo
[object_id] => 10150932300320918
[application] => Array
(
[name] => Photos
[id] => 2305272732
)
[created_time] => 2012-07-02T17:57:23+0000
[updated_time] => 2012-07-02T17:57:23+0000
[comments] => Array
(
[count] => 0
)
)
solution:
cURL - had to use number format with PHP_EOL to solve in cURL.
// $locs = curl call to graph api for /anotherfeed/feed, still need solution for foreach.
$locs=json_decode($returned, true);
$stId=number_format($locs[data][1][story_tags][0][0][id], 0, '', '').PHP_EOL;
echo $stId;
PHP-SDK
solution is same, long numbers in the foreach loop need to be ran through number_format.

Categories