Im looking to use a PHP array obtained from a RESTful service.
They array is just a simple array outputted as follows,
array (
0 =>
stdClass::__set_state(array(
'id' => '375',
'primary_name' => 'Beaufort 3',
'price' => '',
'sqft' => '2435',
'bdrm' => '3',
'bthm' => '2.5',
'display_title' => 'Traditional A1',
'full_img_path' => '',
'thumb_path' => '',
'available_in' => 'a:2:{i:0;s:1:"2";i:1;s:1:"5";}',
'display_first' => '',
)),
)
I'm obtaining the data using file_get_contents but of course its no longer an array at this point. What is the best way to convert this back to a usable array?
I have never seen a service that provides this, probably because it is something people would avoid using, but it does look like it could be something they intend for you to be able to use with eval(). I suppose this could be intended as a convenience. I think they have made an error, though. If you use var_export, (which I assume is how this was generated) on an array like this:
$example = array (
array(
'id' => '375',
'primary_name' => 'Beaufort 3',
'price' => '',
'sqft' => '2435',
'bdrm' => '3',
'bthm' => '2.5',
'display_title' => 'Traditional A1',
'full_img_path' => '',
'thumb_path' => '',
'available_in' => 'a:2:{i:0;s:1:"2";i:1;s:1:"5";}',
'display_first' => '',
)
);
then you would get something you could eval into a variable and use in your code. However, if you var_export an array of anonymous objects instead of an array of associative arrays, you will get the type of response you are getting, which I don't know of any way to use. I would guess they are var_exporting the results of a query and they are using FETCH_OBJ instead of FETCH_ASSOC for the fetch style.
EDIT:
I was looking through the comments on var_export after writing this and came across this way of doing it that should work.
$str = str_replace("stdClass::__set_state", "(object)", $str);
eval('$array=' . $str . ';');
But just because something is possible doesn't mean we should do it.
You can convert it back into an array with eval(). http://php.net/manual/en/function.eval.php
eval('$array='.$response.';');
However, this can be dangerous, because eval will take any PHP code given it - if the service is compromised, your code would execute anything passed to it. JSON, if the service supports it, is much safer and natively supported in PHP since 5.2 via json_decode(). http://php.net/manual/en/function.json-decode.php
Related
I am trying to get a YouTube RSS feed to work but I am struggling to get one of the attributes I need out of it. I have never seen part of the array starting with an # sign so I think it may be some sort of a special element but I'm not sure. Code below and what I have already tried after.
Feed:
<?php
$xml->entry =
SimpleXMLElement::__set_state(array(
'id' => 'yt:video:DjwM9SHJznM',
'title' => 'JD19AT - Joomla! in der Uni - Community-Arbeit als Lehrveranstaltung',
'link' =>
SimpleXMLElement::__set_state(array(
'#attributes' =>
array (
'rel' => 'alternate',
'href' => 'https://www.youtube.com/watch?v=DjwM9SHJznM',
),
)),
'author' =>
SimpleXMLElement::__set_state(array(
'name' => 'J and Beyond e.V.',
'uri' => 'https://www.youtube.com/channel/UCy6ThiEDnalZOd_pgtpBk1Q',
)),
'published' => '2019-03-30T16:49:53+00:00',
'updated' => '2019-05-09T16:56:18+00:00',
));
?>
Code:
$feed = $youtubeChannelFeed;
$xml = simplexml_load_file($feed);
$html = "";
This works $xml->entry->title;
but this doesn't $xml->entry->link it just says "SimpleXML Object"
As it says object I then tried using both -> arrow and ['attribute'] notation.
I tried escaping the # with a \# but that just caused an error.
How can I traverse the tree and get the value of to #attributes->href ?
The way I always try to remember this is that you can use an arrow or brackets to access data in an array or object.
Array begins with A, but it chooses the one that's does not begin with A. Object is the one left over. That's how I remember it at least.
In this case, although it was calling it a SimpleXMLObject it was actually showing me that it's an array in the print_r. So I had to use brackets to access like so:
$xml->entry->link[0]['href']
I couldn't work out how to access #attributes but I remember now that you don't need to know the name to access it, you can do it using number format too.
If I'm honest I don't really know how I could access the first part with arrows as that appears to be an array too.
I want to call the function from an array .My code is
$params = array(
'df' => $this->_data['df'],
'fl' => implode(',', $this->_data['fl']),
'wt' => $this->_data['wt'],
'q' => $this->_data['select'],
'sort' => '',
'fq' => implode(' ', $fq),
'indent' => 'true',
'start' => $this->_data['range'][0],
'rows' => $this->_data['range'][1],
'defType' => $this->_data['defType'],
'qf' => implode(' ', $qf),
);
i want to call function-"WordSplit" from an array:
'q' => WordSplit($this->_data['select']);
Is it possible to do this in PHP?
Thanks in Advance!!!
As has been said, "the answer is, 'yes.'" WordSplit() is a function, therefore a call to that function is a valid expression. It can be used to provide a value for an array-element.
Now, what I would do, instead, is to add a new statement after the existing one:
$params['q'] = WordSplit(params['q']);
Why? Because the very-harried person who's reading our code, someday in the future, might not notice that element 'q' is being handled differently! Purely for the sake of readability (and possible future maintainability), I would choose to do this as a separate statement. The $params array is first "assembled," in a construct where the action for every element in the array is more-or-less the same. Then, element 'q' is manipulated. (And I would place all other such "manipulations" adjacent to this one. "Clarity... Clarity...")
For a client, I'm building a link between the client's application and a third party's application. The third party's application expects fields like below:
<General>
<Signing>
<Signing>
<FieldA></FieldA>
<FieldB></FieldB>
<FieldC></FieldC>
</Signing>
<Signing>
<FieldA></FieldA>
<FieldB></FieldB>
<FieldC></FieldC>
</Signing>
</Signing>
</General>
We're building the input for the link in PHP, by means of a multi-dimensional associative array. So the above XML would compute to the following PHP:
'General' => array(
'Signing' => array(
'Signing' => array(
'FieldA' => '',
'FieldB' => '',
'FieldC' => ''
),
'Signing' => array(
'FieldA' => '',
'FieldB' => '',
'FieldC' => ''
)
)
)
There's a few problems.
There's no such thing as duplicate keys in an associative array. The output would be messed up.
The third party NEEDS it like this, this is just how they set up their application.
Even if there was such a thing as duplicate kets in an associative array, there is no way that would outputto what the third party expects. The Signing would just be overwritten with the last Signing item.
My question is, how do I make a dynamic associative array (so the number of Signings can vary) with duplicate Signing keys that still outputs every instance of Signing, instead of just one Signingfield with just the last instance.
I hope this makes sense. I'm foreign and my brain is chaos so I'm terrible at explaining things.
Thanks in advance!
You cannot express the same data structure literally in PHP, period. You'll have to express it differently and your XML-serialiser will have to translate appropriately between the PHP array structure and the expected XML representation. A sensible PHP array structure would be this:
'General' => array(
'Signing' => array(
array('FieldA' => '', 'FieldB' => '', 'FieldC' => ''),
array('FieldA' => '', 'FieldB' => '', 'FieldC' => ''),
)
)
The XML serialiser would do something akin to:
foreach ($array['General']['Signing'] as $signing) {
$xml->General->Signing->appendChild('Signing')
..
}
How exactly to do this depends on your XML serialisation process. Suffice it to say that the data structure doesn't need to be/can't be literally identical and will require a translation layer.
I have an array that I would like to sort, that should be easy, except that I build my array in a strange manners (for different reasons) that make it hard to sort. Here is my array :
$arrayCEO =array(
'companyName' => array(0=>'name1', 1=>'name2'),
'link' => array (0=>'link1', 1=>'link2'),
'isin' => array (0=>'isin1', 1=>'isin2'),
'mktCap' => array (0=>'mktCap1', 1=>'mktCap2'),
'nbShares' => array (0=>'nbShares1', 1=>'nbShares2'),
'amount' => array (0=>'10', 1=>'20'));
Is that possible to sort by "amount" without breaking the order in the others arrays?
Do you recommend me to rewrite my code to build an array like this one :
$arrayCEO =array(
0 => array ('name' => 'name1', 'link' => 'link1', 'isin' => 'isin1', …),
1 => array ('name' => 'name2', 'link' => 'link2', 'isin' => 'isin2', …));
2 => ...
I know this one would be simple to sort but it's a lot of work to rewrite my piece of code.
Thanks,
Dorian
It makes a lot more sense to rewrite your arrays to store in the more conventional format you described - (It's always better to organise things in decreasing magnitude 'Root > rows > fields' instead of 'Root > fields > rows')
If you didn't want to change you could probably use the usort function and roll your own sorting method, but it might be a bit of work to make it play nicely.
I'm probably missing something simple here but I can't seem to find a way to build a query that will allow me to update a match in a group of nested values.
I have a document like this for a blog app I've been working on (currently uses MySQL):
array (
'_id' => new MongoId("4bc8dcee8ba936a8101a0000"),
'created' => '20100418-201312 +0000',
'post-title' => 'Some Post Title',
'post-body' => 'Blah Blah Blah Blah.',
'post-blog-name' => 'default',
'post-comments' =>
array (
0 =>
array (
'comment-title' => 'Test1',
'comment-body' => 'asdf1',
'created' => '20100418-214512 +0000',
'owner' => 'User1',
),
1 =>
array (
'comment-title' => 'Test2',
'comment-body' => 'asdf2',
'created' => '20100418-214512 +0000',
'owner' => 'User2',
),
),
'owner' => 'zach',
'updated' => '20100418-201312 +0000',
)
I'd like to be able to build a query that can search 'comment-title' for a match and then allow me to update/change/delete data as needed.
Obviously I can perform an update using a query which includes the key value. Something like this works:
$collection->update(
array("post-comments.0.comment-title" => $_POST['comment-title']),
array('$set' => array('entries.0' => array('comment-title' => $_POST['comment-title'], 'comment-body' => $_POST['comment-body'], 'owner' => $_SESSION['username'], 'updated' => gmdate('Ymd\-His O')))));
But I expect I'm missing something that would allow me to leave out the key and still be able to match one of the nested arrays based on a value (in this example the 'comment-title').
Anyway, sorry, this probably isn't the best example and I probably will end up using the keys in comments to identify them (comment #) but since nesting and creating rather complex objects seem to be a few of Mongodbs strong points I'm just hoping someone can point out what it is I might be missing.
A query to remove or update all comments by a specific user (say a user the blog author just black-listed) might be a better example. I'm not sure how I'd do this short of pulling out the entire document and then iterating through the nested arrays using PHP.
try ... notice I removed the "key"
$collection->update(array("post-comments.comment-title" ...
Cheers!