So I got a simple function that works, but I'm trying to evolve my experince wtih OOP and try to make sure I can use my code without having to edit everything.
Here is my simple function
$xmlfeed = file_get_contents('/forum/syndication.php?limit=3');
$xml = new SimpleXMLElement($xmlfeed);
$result = $xml->xpath('channel/item/title');
while(list( , $node) = each($result)) {
echo $node;
}
Now so far I got to this point:
class ForumFeed {
private function getXMLFeeds($feed = 'all'){
/*
Fetch the XML feeds
*/
$globalFeedXML = file_get_contents('/forum/syndication.php?limit=3');
$newsFeedXML = file_get_contents('/forum/syndication.php?fid=4&limit=3');
/*
Turn feed strings into actual objects
*/
$globalFeed = new SimpleXMLElement($globalFeedXML);
$newsFeed = new SimpleXMLElement($newsFeedXML);
/*
Return requested feed
*/
if ($feed == 'news') {
return $newsFeed;
} else if ($feed == 'all') {
return $globalFeed;
} else {
return false;
}
}
public function formatFeeds($feed) {
/*
Format Feeds for displayable content..
For now we're only interested in the titles of each feed
*/
$getFeed = $this->getXMLFeeds($feed);
return $getFeed->xpath('channel/item/title');
}
}
$feeds = new ForumFeed();
However when trying to echo $feeds->formatFeeds('all'); it doesn't return anything. The results is blank.
What am I doing wrong?
var_dump($feeds->formatFeeds('all')); returns
array(3) {
[0]=>
object(SimpleXMLElement)#3 (0) {
}
[1]=>
object(SimpleXMLElement)#4 (0) {
}
[2]=>
object(SimpleXMLElement)#5 (0) {
}
}
According to PHPs documentation SimpleXMLElement::xpath returns an array of SimpleXMLElements or false on error. Maybe var_dump($feeds->formatFeeds('all')); prints something you then can use to debug.
Edit: The XPath query returns results, so probably there is a logical error in your query or the returned elements don't have content.
Related
I may not word this issue properly, so here's what am trying to achieve.
array {
[0]=> {
["Abilities"]=> { ["Numerical"]=> 3 }
}
[1]=> {
["Abilities"]=> { ["Verbal"]=> 1 }
}
[2]=> {
["Domain"]=> { ["Programming"]=> 0 }
}
}
to
array {
[0]=> {
["Abilities"]=> { ["Numerical"]=> 3 ["Verbal"]=> 1 }
}
[1]=> {
["Domain"]=> { ["Programming"]=> 0 }
}
}
I get this array from an external source so I need optimized this way to use it.
The array you're getting from an external source is like a set of separate branches you need to merge into a single tree. You can use a recursive function to create the "optimized" structure you're going for. A recursive approach should work regardless of the depth of each branch.
function merge_branches(array $branches): array
{
$merge = function ($node, &$tree) use (&$merge) {
if (is_array($value = reset($node))) {
$merge($value, $tree[key($node)]); // merge branch node recursively
} else {
$tree[key($node)] = $value; // set leaf node to value
}
};
$tree = [];
foreach ($branches as $branch) {
$merge($branch, $tree);
}
return $tree;
}
$optimized = merge_branches($external);
I have a return value and I var_dump() to get the data.
var_dump($values)
this is the result:
object(WP_Error)#171 (2) { ["errors":"WP_Error":private]=> array(1) { ["upload_error"]=> array(1) { [0]=> string(28) "0B1n5jy1RsUExUWNCN01GeXBvWmM" } } ["error_data":"WP_Error":private]=> array(0) { } }
I am new with PHP Object retrieving I tried foreach but noting happens.
what I am trying to do is to get this value:
["upload_error"]=> array(1) { [0]=> string(28) "0B1n5jy1RsUExUWNCN01GeXBvWmM" }
the 0B1n5jy1RsUExUWNCN01GeXBvWmM that set on upload_error
WP_Error is a php class, your values is a instance. see https://codex.wordpress.org/Class_Reference/WP_Error for detail
if you want to get error, you can't get it directly because it is private( although you can see it in var_dump), the doc above will tell you how to get it via provided public methods.
the following code snippet may give you a better understanding for using foreach on a class instance. you can look at manual for more detail. http://php.net/manual/en/language.oop5.iterations.php
class WP_Error_Example
{
private $errors = array();
public $pk = 1;
}
$e = new WP_Error_Example();
$e2 = new WP_Error_Example();
// #1,#2 in var_dump shows how many instance?
var_dump($e);
var_dump($e2);
// only public value
foreach ($e as $k => $v) {
var_dump($k, $v);
}
Note: you need to save this to a single file and run it using commandline. eg:php demo.php PS: var_dump it not pretty in commandline.
This question already has answers here:
Convert a PHP object to an associative array
(33 answers)
Closed 6 months ago.
I'm using amazon product advertising api. Values are returned as a multidimensional objects.
It looks like this:
object(AmazonProduct_Result)#222 (5) {
["_code":protected]=>
int(200)
["_data":protected]=>
string(16538)
array(2) {
["IsValid"]=>
string(4) "True"
["Items"]=>
array(1) {
[0]=>
object(AmazonProduct_Item)#19 (1) {
["_values":protected]=>
array(11) {
["ASIN"]=>
string(10) "B005HNF01O"
["ParentASIN"]=>
string(10) "B008RKEIZ8"
["DetailPageURL"]=>
string(120) "http://www.amazon.com/Case-Logic-TBC-302-FFP-Compact/dp/B005HNF01O?SubscriptionId=AKIAJNFRQCIJLTY6LDTA&tag=*********-20"
["ItemLinks"]=>
array(7) {
[0]=>
object(AmazonProduct_ItemLink)#18 (1) {
["_values":protected]=>
array(2) {
["Description"]=>
string(17) "Technical Details"
["URL"]=>
string(217) "http://www.amazon.com/Case-Logic-TBC-302-FFP-Compact/dp/tech-data/B005HNF01O%3FSubscriptionId%3DAKIAJNFRQCIJLTY6LDTA%26tag%*******-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3DB005HNF01O"
}
}
[1]=>
object(AmazonProduct_ItemLink)#17 (1) {
["_values":protected]=>
array(2) {
I mean it also has array inside objects. I would like to convert all of them into a multidimensional array.
I know this is old but you could try the following piece of code:
$array = json_decode(json_encode($object), true);
where $object is the response of the API.
You can use recursive function like below:
function object_to_array($obj, &$arr)
{
if (!is_object($obj) && !is_array($obj))
{
$arr = $obj;
return $arr;
}
foreach ($obj as $key => $value)
{
if (!empty($value))
{
$arr[$key] = array();
objToArray($value, $arr[$key]);
}
else {$arr[$key] = $value;}
}
return $arr;
}
function convertObjectToArray($data) {
if (is_object($data)) {
$data = get_object_vars($data);
}
if (is_array($data)) {
return array_map(__FUNCTION__, $data);
}
return $data;
}
Credit to Kevin Op den Kamp.
I wrote a function that does the job, and also converts all json strings to arrays too. This works pretty fine for me.
function is_json($string) {
// php 5.3 or newer needed;
json_decode($string);
return (json_last_error() == JSON_ERROR_NONE);
}
function objectToArray($objectOrArray) {
// if is_json -> decode :
if (is_string($objectOrArray) && is_json($objectOrArray)) $objectOrArray = json_decode($objectOrArray);
// if object -> convert to array :
if (is_object($objectOrArray)) $objectOrArray = (array) $objectOrArray;
// if not array -> just return it (probably string or number) :
if (!is_array($objectOrArray)) return $objectOrArray;
// if empty array -> return [] :
if (count($objectOrArray) == 0) return [];
// repeat tasks for each item :
$output = [];
foreach ($objectOrArray as $key => $o_a) {
$output[$key] = objectToArray($o_a);
}
return $output;
}
This is an old question, but I recently ran into this and came up with my own solution.
array_walk_recursive($array, function(&$item){
if(is_object($item)) $item = (array)$item;
});
Now if $array is an object itself you can just cast it to an array before putting it in array_walk_recursive:
$array = (array)$object;
array_walk_recursive($array, function(&$item){
if(is_object($item)) $item = (array)$item;
});
And the mini-example:
array_walk_recursive($array,function(&$item){if(is_object($item))$item=(array)$item;});
In my case I had an array of stdClass objects from a 3rd party source that had a field/property whose value I needed to use as a reference to find its containing stdClass so I could access other data in that element. Basically comparing nested keys in 2 data sets.
I have to do this many times, so I didn't want to foreach over it for each item I need to find. The solution to that issue is usually array_column, but that doesn't work on objects. So I did the above first.
Just in case you came here as I did and didn't find the right answer for your situation, this modified version of one of the previous answers is what ended up working for me:
protected function objToArray($obj)
{
// Not an object or array
if (!is_object($obj) && !is_array($obj)) {
return $obj;
}
// Parse array
foreach ($obj as $key => $value) {
$arr[$key] = $this->objToArray($value);
}
// Return parsed array
return $arr;
}
The original value is a JSON string. The method call looks like this:
$array = $this->objToArray(json_decode($json, true));
How?
More to the point...
this:
$url = 'http://php.net/manual/en/class.domelement.php';
$client = new Zend_Http_Client($url);
$response = $client->request();
$html = $response->getBody();
$dom = new Zend_Dom_Query($html);
$result = $dom->query('div.note');
Zend_Debug::dump($result);
gives me this:
object(Zend_Dom_Query_Result)#867 (7) {
["_count":protected] => NULL
["_cssQuery":protected] => string(8) "div.note"
["_document":protected] => object(DOMDocument)#79 (0) {
}
["_nodeList":protected] => object(DOMNodeList)#864 (0) {
}
["_position":protected] => int(0)
["_xpath":protected] => NULL
["_xpathQuery":protected] => string(33) "//div[contains(#class, ' note ')]"
}
And I cannot for the life of me figure out how to do anything with this.
I want to extract the various parts of the retrieved data (that being the div with the class "note" and any of the elements inside it... like the text and urls) but cannot get anything working.
Someone pointed me to the DOMElement class over at php.net but when I try using some of the methods mentioned, I can't get things to work. How would I grab a chunk of html from a page and go through it grabbing the various parts? How do I inspect this object I am getting back so I can at least figure out what is in it?
Hjälp?
The Iterator implementation of Zend_Dom_Query_Result returns a DOMElement object for each iteration:
foreach ($result as $element) {
var_dump($element instanceof DOMElement); // always true
}
From the $element variable, you can use any DOMElement method:
foreach ($result as $element) {
echo 'Element Id: '.$element->getAttribute('id').PHP_EOL;
if ($element->hasChildNodes()) {
echo 'Element has child nodes'.PHP_EOL;
}
$aNodes = $element->getElementsByTagName('a');
// etc
}
You can also access the document element, or you can use Zend_Dom_Query_Result to do so:
$document1 = $element->ownerDocument;
$document2 = $result->getDocument();
var_dump($document1 === $document2); // true
echo $document1->saveHTML();
If I have something like this from the server side, from a fetch:
array(1) { [0]=> array(1) { ["nome"]=> string(7) "aaaa.br" } } [{"nome":"aaaa.br"}]
The json of the above is:
[{"nome":"aaaa.br"}]
This Works:
parse: function(data) {
return $.map(eval('('+data+')'), function(result) {
return {
data: result,
value: result.nome,
result: result.nome
}
});
}
The result is parsed successfully.
If, instead of fetch, I change to fetchAll, the dump gets like this (here only the first index as example):
array(65) { [0]=> array(1) { ["nome"]=> object(stdClass)#7 (1) { ["nomeDominio"]=> string(7) "aaaa.br" } }
The json conversion of the above:
string(2632) "[{"nome":{"nomeDominio":"aaaa.br"}}
Here, the result is not successfully parsed.
So I believe something needs to be changed on the js side.
But I'm absolutely clueless.
UPDATE:
The nomeDominio is from the fetchObj PDO method, and corresponds to the column name on the database. It's a natural behaviour for fetch with PDO when FETCH::OBJ option is used.
The php part of this js is:
$keyword = addslashes($_GET["q"]);
$comandos = new ComandoController();
$arr = $comandos->recebeNomeDominios($keyword);
if(is_array($arr))
{
echo json_encode($arr);
}
public function recebeNomeDominios($keyword)
{
$DominioDao = new DominioDao();
$objecto = $DominioDao->recebeNomeDominios($keyword);
return $this->jsonArray($objecto);
}
private function jsonArray($objecto)
{
$json = array();
if(isset($objecto) && !empty($objecto))
{
foreach($objecto as $obj)
{
$json[] = array('nome' => $obj);
}
}
return $json;
}
Finally:
public function recebeNomeDominios($keyword)
{
try
{
$stmt = $this->_dbh->prepare("SELECT d.nomeDominio FROM dominio d WHERE d.nomeDominio LIKE '%".$keyword."%'");
$stmt->execute();
$resultado = $stmt->fetch(PDO::FETCH_OBJ);
return $resultado;
}
catch (PDOException $ex)
{
echo "Erro: " . $ex->getMessage();
}
}
Any advice?
MEM
$comandos = new ComandoController();
$arr = $comandos->recebeNomeDominios($keyword);
echo json_encode($arr);
class ComandoController {
public function recebeNomeDominios($keyword)
{
$stmt = $this->_dbh->prepare('
SELECT
d.nomeDominio as nome
FROM
dominio
WHERE nomeDominio LIKE :keyword
');
$stmt->bindParam(':keyword', $keyparam);
$keyparam = '%'.str_replace('%', '\\%', $keyword) . '%';
$stmt->execute();
return $stmt->fetchALL(PDO::FETCH_ASSOC);
}
...
If you return one array (fetch) then you need to collect data from it like this
var name = data.name;
var age = data.age;
var gender = data.gender;
// Do something with values here
If you are using fetchAll, this will presumably return an array of arrays (a multidimensional array) which you will need to iterate over. From looking at $.map it looks like your using jQuery. Iterate over the multidimensional array like this
jQuery.each(data, function() {
name = this.name;
age = this.age;
gender = this.gender;
// Do something with values here
});