I'm trying to pull the links off of a bunch of webpages and report them in tables. I have this function, get_links($pageId), which is supposed to get the contents of the page and pull out the values and href attributes of each anchor tag.
function get_links($pageId) {
$page_contents = file_get_contents('http://www.mysite.com/?p='.$pageId);
$html = new DOMDocument();
#$html->loadHTML($page_contents);
$anchors = $html->getElementsByTagName('a');
$link_array = array();
foreach($anchors as $anchor) {
if (!empty($anchor->nodeValue)) {
$text = $anchor->nodeValue;
$link = $anchor->getAttribute('href');
$link_array[$text] = $link;
}
}
return $link_array;
}
When I run this function on one of the pages, it returns nothing. For example, if I call:
$page_links = get_links('someId');
foreach($page_links as $text->$link) {
//my print functions
};
I get "Fatal error: Cannot access empty property" for the foreach line.
Echoing $text and $link in the foreach($anchors) loop works fine. So does echoing the values from $link_array after the loop. But echoing the keys doesn't. If I put in this test right after the loop:
foreach($link_array as $text->$link) {echo $text;}
I get this error: "Catchable fatal error: Object of class stdClass could not be converted to string."
Why would it print alright during the loop but be treated as an object when I put it in an array to return?
You're trying to assign the iterated valutes of the foreach loop to an object's attribute. I think you actually want
foreach($link_array as $text => $link) { echo $text;}
instead.
Saying $text->$link is telling PHP to take the current foreach iterated value, and assign it to a $link property of the $text object - however, $text and $link are not objects at that point, so you're assigning to non-existence attributes of a non-existent object, causing the "Cannot access empty property" error.
Related
In the following code, I retrieve with DOM a list of nodes from an xml document. Then I would like to select, by their tag name, some of these nodes.
$index = new DOMDocument();
$index->load('index.xml');
$xpath = new DOMXpath($index);
$related_notions = $xpath->query("/index/notion[name='" . $name . "']/relations/*"); // the variable $name is dynamically defined previously in the script
foreach ($related_notions->getElementsByTagName("superordinate") as $item) {
// do something
}
I get the following error: Uncaught Error: Call to undefined method DOMNodeList::getElementsByTagName()
I don't understand why the method getElementsByTagName() is not defined for DOMNodeList. After all, getting elements by their name seems to me something obvious that one might want to do with a node list. At any rate, my actual question is: How can I do what I want to do? That is, in the absence of the method getElementsByTagName(), how do I get elements by tag name from a node list?
Thanks in advance for your help!
I found a solution to my problem, namely to test for the nodeName with an if statement inside the foreach:
$index = new DOMDocument();
$index->load('index.xml');
$xpath = new DOMXpath($index);
$related_notions = $xpath->query("/index/notion[name='" . $name . "']/relations/*");
foreach ($related_notions as $item) {
if ($item->nodeName == "superordinate") {
// do something
}
}
How can I use a getElementsByTagName() on a DOMElement in PHP?
I want to go through the second cell, td, in every row, tr, in a table to get the rows title:
function getDetails($url) {
$doc = new DOMDocument();
#$doc->loadHTML(file_get_contents($url));
$table = $doc->getElementById("table");
$rows = $doc->getElementsByTagName("tr");
foreach ($rows as $row) {
$items = $row->getElementsByTagName("td");
$title = $items->item(1)->getElementsByTagName('a')->item(0)->nodeValue;
}
}
Although, when I try to run it I get this error on $title = $items->item(1)->getElementsByTagName('a')->item(0)->nodeValue;:
Fatal error: Uncaught Error: Call to a member function getElementsByTagName() on null
I've tried to find a solution to the problem but didn't find anything. Do anyone know how I can fix this or should I do it in another way?
I'm trying to parse html content, for the value stored in the name tag.
My current try looks like the following:
function getAuthToken(){
$html = file_get_contents('url');
$values = array();
foreach($html->find('input') as $element)
{
$values[$element->name] = $element->value;
}
print_r($values);
}
What am I doing wrong?
$html in your code is not an object its a string (the results of file_get_contents).
$object->name is a class object
$array[key] is an array element
Neither of these in your code will do what you want to achieve with the result of file_get_contents because your $html var is a string, you need to do some string parsing to get the desired results.
You can check that with:
echo gettype($html);
You can also just echo out $html to find out what the string looks like to give you a better idea of what you are working with, for instance, is there a common character that you can explode the sting with an so getting an array to work with within your foreach.
example:
$newarray = explode('&', $html);
foreach ($newarray as $key => $value) {
//do your thing
}
I am trying to extract the data stored in a list. The troubling piece is the "custom-data" entity.
<li id="myid" custom-data="123456789" class="search-query">
...lots of child elements
I get all the string data with querying DomXPath object for "search-query" and than extract it with this the code below.
$id = $exampleXPath->query("//li[#class='search-query']");
foreach ($id as $element) {
$nodes = $element->childNodes;
foreach ($nodes as $node) {
echo "$node->nodeValue<br>";
}
}
I would like to also get the value of "custom-data" of each "search-query" object, but I don't how to get it. Any ideas?
You already have reference to all "search-query" elements, so getting the attribute should be as straightforward as calling getAttribute("attribute_name") on each element:
$custom_data = $element->getAttribute("custom-data");
I'm not sure if this is even possible after trying to figure it out for hours but here goes...
I have an class, UserPicture, which has properties for filename, filetype, created etc. (i.e. it doesn't store the actual picture as a blob, rather references it by using $filename.$filetype).
I want to be able to have a page that displays all of a user's pictures, so I need to retrieve all rows from the DB relevant to that user. I've got the associative array out of the DB successfully and have used the following code to create the object, which works as I have tested the output of it by echoing it...
$result=query("SELECT * FROM pictures WHERE user_id=$user_id");
// Returns associative array with numerous succesfully.
$pictures = array();
foreach($result as $row) {
$pictures = new UserPicture($row);
}
This kinda works but I only get the last row as an object in the array. So I have tried array_push...
foreach($result as $row) {
array_push($pictures, new UserPicture($row));
}
...and I've tried using $pictures[]=new UserPicture($row), but both just give me the following error...
Catchable fatal error: Object of class UserPicture could not be converted to string in user_picture_manage.php on line 72
If anyone could please shed any light on what I'm doing wrong that would be very helpful!
Many thanks,
Steve
You're overwriting the $pictures variable in your above code. You need to add a new key for each row. The following should do the trick:
$result=query("SELECT * FROM pictures WHERE user_id=$user_id");
// Returns associative array with numerous succesfully.
$pictures = array();
foreach($result as $row) {
$pictures[] = new UserPicture($row);
}
Note where I've added squared braces ([]). For each iteration in the foreach loop, a new key will be added to the $pictures array containing the new UserPicture class as the value.
You should then be able to iterate over your new $pictures array as follows:
foreach ($pictures as $picture) {
$src = $picture->filename . "." . $picture->filetype;
echo '<img src="<?php echo $src; ?>" alt="" />';
}