foreach function only one shows - php

New to PHP so don`t be mad if the question is really stupid.
i have made this code :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
img {float: left; margin-right: 30px; margin-bottom: 10px;}
</style>
<script src="js/jquery-1.7.2.min.js"></script>
<script src="js/lightbox.js"></script>
<link href="css/lightbox.css" rel="stylesheet" />
<title>Untitled Document</title>
</head>
<body>
<?php
// specify url of xml file
$url = "http://travelplaza.ro/turcia/belek/Belek.xml" ;
// get xml file contents
$xml = simplexml_load_file($url);
// loop begins
foreach ($xml->hotel[0] as $hotel) {
echo $hotel["hotelname"];
echo "&nbsp";
echo $hotel["stars"];
echo "<p>";
echo $hotel->description . "</br>";
echo "</p>";
echo "<p>";
echo "</p>";
}
foreach ($xml->hotel[0]->images[0] as $i) {
echo '<a href="' . $i["url"] . '" rel="lightbox"><img src="' . $i["url"] . '" width="100" height="100">';
echo "</a>";
}
Above is the xml itself..of course there are many hotels.
The result that i want is to have the title, description and pictures from the feed for the first hotel , then the second one and so on.
Instead i get only the images. If i remove the atributes [0] it gives a list with al the hotels with name , description and pics. Where is my mistake? I just want to show the hotel,description and the images. Any help would be apreciated.
Thank you.
EDIT: If i want to show only hotel[45] with description and images ?
the xml looks like so :
<hotels>
<hotel hotelcode="xxx">
<description>
bla bla
</description>
<images>
<image url="http"/>
</images>
</hotel>
The above repeats and on the last one i have the end tag.
The xml file is like this:
http://travelplaza.ro/turcia/belek/Belek.xml

Since you don't post the content of that xml file we can only guess its content...
Most likely $xml->hotel is an array of hotels. However you iterate over the frist element in that, not over the list of hotels. Try this instead:
foreach($xml->hotel as $hotel)
For the images: most likely you have to place the second foreach loop addressing the images inside the first loop, since each hotel most likely can hold references to several images. So the second loop should look something like this:
foreach($hotel->images as $i)
So the final code probably is meant to be like this:
$url = "http://travelplaza.ro/turcia/belek/Belek.xml";
// get xml file contents
$xml = simplexml_load_file($url);
// loop over the hotels
foreach($xml->hotel as $hotel){
echo $hotel["hotelname"]."&nbsp".$hotel["stars"]."\n";
echo "<p>\n".$hotel->description."\n</p>\n";
// loop this hotels images
echo "<p>\n";
foreach($hotel->images as $image) {
echo '<a href="'.$image["url"].'" rel="lightbox">'."\n";
echo '<img src="'.$image["url"].'" width="100" height="100">'."\n";
echo "</a>"\n;
}
echo"</p>\n";
}
But as said: without more details we can only guess...

hotel[0] means the first hotel in the list; when you loop over that, SimpleXML assumes you want its children. In this case, each hotel has two children, one description and one images.
You want each hotel in turn, that is, all the elements called hotel so remove the [0]:
foreach($xml->hotel as $hotel)
For the images, you want to get them at the same time as the name and description, but you have two separate loops, so you don't start looking at images until you've displayed all the descriptions.
Move the image loop inside the main loop, and change it to look at whichever hotel you're currently examining. Again, you don't want the [0], but looking at the XML there are multiple image elements inside one images element, so you need this:
foreach($hotel->images->image as $i)
(The [0] in this case sort of works as well, because $hotel->images[0] is the first and only images element, and its children are the individual image elements. I think the above better shows your intention.)

try this:
<?php
$url = "http://travelplaza.ro/turcia/belek/Belek.xml";
// get xml file contents
$xml = simplexml_load_file($url);
// loop begins
foreach($xml->hotel as $hotel) {
echo <<<EOD
<div>
<p>{$hotel['hotelname']}</p>
<p>{$hotel['stars']};</p>
<p>{$hotel->description}</p>
<p>
EOD;
foreach ($hotel->images[0] as $i) {
echo <<<EOD
<p>
<img src="{$i["url"]}" width="100" height="100">'
</p>
EOD;
}
echo <<<EOD
</div>
EOD;
}
?>

Related

How does a php program emit an svg image? [duplicate]

I want to read an SVG file and get the SVG tag from this file (because I want to show svg in html e.g. <div><svg>...</svg></div> without the xml header).
And show this svg tag in browser like HTML - print this SVG TAG like SVG image. Becouse now I'm gettong wrong output "DOMNodeList Object ( [length] => 1 ) ".
PHP
$doc = new DOMDocument();
$doc->load('http://example.com/logo.svg');
$svg = $doc->getElementsByTagName('svg');
echo "<div style='width: 100%, height: 100%; '>";
print_r($svg); // DOMNodeList Object ( [length] => 1 )
echo "</div>";
I found solution, but it is not exactly the answer for my question. So I will not mark it as a answer, but I leave here this solution. Maybe there will be somebody who will need it... :)
I just read file content, then I look for position of string "< svg" , and then substract this piece of code.
PHP
<?php
$svg_file = file_get_contents('http://example.com/logo.svg');
$find_string = '<svg';
$position = strpos($svg_file, $find_string);
$svg_file_new = substr($svg_file, $position);
echo "<div style='width:100%; height:100%;' >" . $svg_file_new . "</div>";
?>
You were definitely on the right track with you first attempt. I could spot two small problems though:
As you may have guessed, you tried to output a DOMNodeList object, which is what you will get from a call to getElementsByTagName. As the name implies, it is not a single node object but a collection of those so you would be interested in just the first found svg node (item(0) in code below).
DOM* instances do not automatically get converted into strings when printed. Use the C14N() method instead for output.
Code:
$svg_file = <<<END_OF_SVG
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width='300px' height='300px'>
<title>Test</title>
<circle cx='150' cy='150' r='70' style='fill: gold;' />
</svg>
END_OF_SVG;
$doc = new DOMDocument();
$doc->loadXML($svg_file);
$svg = $doc->getElementsByTagName('svg');
echo '<div style="width: 100%; height: 100%;">';
echo $svg->item(0)->C14N();
echo '</div>';
This seems to be the first hit for this topic in Google. Based on the other replies and what the original question was about, the answer to the original question is that getElementsByTagName returns an array, so you need to take the the first item in that array and use the saveHTML() method of DOMDocument. I made a short utility function to do just that.
function print_svg($file){
$iconfile = new DOMDocument();
$iconfile->load($file);
echo $iconfile->saveHTML($iconfile->getElementsByTagName('svg')[0]);
}

Traverse HTML file elements with PHP

I need to read an HTML file (that I don't know how it will look like) and go through all its elements. For those elements that have an innerhtml text, I'd like to grab or modify that. I've searched exhaustively but can't find something that does what I need.
Here's an example HTML file:
<!DOCTYPE html>
<html lang="en">
<body>
<p> 1st text I need</p>
2nd text I need
<table>
<tr>
<td>3rd text I need</td>
</tr>
</table>
</body>
</html>
Here's what I need to accomplish:
Traverse file
Find which elements have innerhtml
Grab or modify the text
Save the file
In the file above almost all elements have text but complex files won't.
I can use DOMDocument() to loop through specific types of nodes but I don't know what I'm going to encounter until a file is selected.
I thought the code below would do it but it prints just the file name during the loop.
<?php
include 'functions.php';
$doc = new DOMDocument();
$doc->loadHTMLFile('test.html');
showDOMNode($doc);
function showDOMNode($domNode) {
foreach ($domNode->childNodes as $node)
{
if($node->nodeName !="#text") {
echo $node->nodeName . ' ';
echo $node->nodeType . ' ';
echo $node->textContent . '<br>';
if($node->hasChildNodes()) {
showDOMNode($node);
}
}
}
}
?>
Here's what I get:
html 10
html 1 1st text I need 2nd text I need 3rd text I need
body 1 1st text I need 2nd text I need 3rd text I need
p 1 1st text I need
a 1 2nd text I need
table 1 3rd text I need
tr 1 3rd text I need
td 1 3rd text I need
As you can see, when the textContent seems to show the text for all child nodes while I need the specific one for each node. Any help is much appreciated.

Scrape an H1 element on the current page in PHP

I'm currently working with Wordpress. I have a hook that runs before a <title> attribute is populated with text that a user enters in the dashboard.
Now I want to set a default title of each page to equal an <h1> attribute text value on a current page. A fragment of the callback function for the hook I'm working with would look like:
if (!$seoTitle) {
$seoTitle = '<....>';
}
return $seoTitle;
I want seoTitle to default to an <h1> element text on the current page. Is it doable? How can I achieve this?
I'm not totally sure how you get your HTML but you could parse it with the built in DOM parser.
<?php
$html = "<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1>This is a Heading one</h1>
<p>This is a paragraph.</p>
<h1>This is a Heading two</h1>
<p>This is a paragraph.</p>
<h1>This is a Heading three</h1>
<p><a href='testwww'> This is a paragraph.</a></p>
</body>
</html>";
$dom = new DOMDocument();
$dom->loadHTML($html);
//If you want to get it from a website you could do the following:
//$dom->loadHTML(file_get_contents('http://www.w3schools.com/'));
// iterate through the html to get all h1 text
foreach($dom->getElementsByTagName('h1') as $heading) {
$h1 = $heading->nodeValue;
echo $h1 . "<br>";
}
?>
Assuming you have your HTML content within a variable and doing this after the page has fully loaded please take a look at the below example:
<?php
$htmlContent = '<html><body><h1>HELLO</h1></body></html>'; // change this to what you need
$seoTitle = preg_replace('/(.*)<h1>([^>]*)<\/h1>(.*)/is', '$2', $htmlContent);
echo $seoTitle; // will output: HELLO
?>
echo "<h1>".(string)$seoTitle."</h1>";
Should work. You can also break out of the php ?> and then type regular html and then break in when you wanna echo the variable.

Personal project: using while loops

I am new to PHP. I am trying to create a simple personal project where several coins move around the page when users refresh it from their browser. I keep on getting a weird error ().
This is what my file looks like:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Treasure Map</title>
</head>
<body style="background-image:url(Bluemap.jpg); background-repeat: no-repeat">
<?php
$numberOfCoins = rand(3, 10);
while ($numberOfCoins) {
$xPosition = rand("10", "650");
$yPosition = rand("10", "400");
print '<div style="position: absolute;';
print 'left:' . $xPosition . 'px;';
print 'top:' . $yPosition . 'px">';
print '<img src="goldCoin.png" height="50px"/>';
print '</div>';
$numberOfCoins--;
}
?>
</body>
</html>
what am I doing wrong?
The file is an HTML document, therefore it cannot run PHP code.
You need to rename it from index3.html to index3.php and also make sure you are running it on a server that runs PHP
You should save the file as .php. This just shows the code itself, which means that it is not parsed.
Apart from that, your code is slightly off too.
The variable $numberOfCoins now contains a random number between 3 and 10. If you want to iterate a random number of times, an if loop might be more convenient:
$numberOfCoins = rand(3,10);
for($i = 0; $i < $numberOfCoins; $i++)
{
}

find if a img have "alt", if not then add from array ( serverside )

first I need to find all img in the sites,
and then check if the img have the "alt" attribute, if image have the attribute it'll be escaped and if it not have one or the alt is empty,a string will be randomly added to img from a list or array.
here is how you do it with javascript:
find if a img have alt in jquery if not then add from array
but it did not help me because according to this:
How do search engines crawl Javascript?
search bots can't read it , if you use JavaScript you need to use server-side language to add keyword to img alt.
what next? php? can i do it with a simple code?
Well, import it into an DOMDocument object and find all images inside.
Seems rather trivial. See the DOMDocument class
Here's my code for the problem:
<?php
$html = <<<HTML
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<p>
<img src="test.png">
<img src="test.jpg" alt="Testing">
<img src="test.gif">
</p>
</body>
</html>
HTML;
$dom = new DOMDocument();
$dom->loadHTML($html);
$images = $dom->getElementsByTagName("img");
foreach ($images as $image) {
if (!$image->hasAttribute("alt")) {
$altAttribute = $dom->createAttribute("alt");
$altAttribute->value = "Ready Value!";
$image->appendChild($altAttribute);
}
}
echo $dom->saveHTML();

Categories