How to combine two PHP 'foreach' loops - php

I'm trying to parse a really simple HTML document with some xpath. There are a total of 20 images and 20 links. My only goal is to get each link applied to it's corresponding image.
My current code below is returning each image a bunch of times. So for example, that first image, which is currently showing 20 times, has a different link applied to it with each instance. So instance #1 of image #1, has link #1 applied to it, instance #2 of image #1 has link #2 applied to it, and so on.
What I want to do is include each image once and apply the corresponding link to it, so I have 20 images, with their corresponding links applied to them. I'm pretty sure I need to combine my two foreach functions, but I'm not quite sure how to do that. Any help would be awesome, thanks guys.
foreach ( $images = $xpath->query("//div[#class='image']//a//img") as $image )
{
foreach ( $links = $xpath->query("//div[#class='image']//a") as $link )
echo "<a href='" . $link->getAttribute( 'href' ) . "'><img src='" . $image->getAttribute( 'src' ) . "'</a>", "\n";
}

Expanding on Ignacio's idea...
First, query for all anchor elements containing images
$anchors = $xpath->query('//div[#class="image"]//a[img]');
Then, use the anchor as the context for the image search
foreach ($anchors as $anchor) {
$images = $anchor->getElementsByTagName('img');
$img = $images->item(0);
printf('<img src="%s">%s',
$anchor->getAttribute('href'),
$img->getAttribute('src'),
PHP_EOL);
}
Update
To me, this seems a much more appropriate job for an XSL transformation

OK so if I understand correctly, after doing the xpath queries you'd end up with two arrays, each with the same number of elements, and they're all matched, meaning $images[x] needs $links[x] for any value of x.
Something like this may work:
$images = $xpath->query("//div[#class='image']//a//img");
$links = $xpath->query("//div[#class='image']//a");
foreach ( $images as $index => $image )
{
echo "<a href='" . $links[$index]->getAttribute( 'href' ) . "'><img src='" . $images[$index]->getAttribute( 'src' ) . "'</a>", "\n";
}

Related

Search text files and display results with PHP

I have a folder (blogfiles/posts) with various text files, numbered (1.txt, 2.txt, 3.txt...) and they each hold a post for a blog (I haven't learned SQL yet). I'm trying to make a search engine for it that will take a query from a text box (done with this part), then search the files for each word in the query, and return the results (possibly in order of the number of times the word occurs).
Each text file looks like this:
Title on Line 1
Date Posted on Line 2 (in Month Date, Year form)
Post body to search on lines 3 and up
I currently have this code:
<?php
$q = $_GET["q"];
$qArray = explode(" ", $q);
//preparing files
$post_directory = "blogfiles/posts/";
$files = scandir($post_directory, 1);
$post_count = (count($files)) - 2;
$files = array_pop($files); // there are 2 server files I want to ignore (#1)
$files = array_pop($files); // there are 2 server files I want to ignore (#2)
foreach ($files as $file) {
//getting title
$post_path = $post_directory . $file;
$post_filecontents = file($post_path);
$post_title = $post_filecontents[0];
echo "<tr><td>" . $post_title . "</td></tr>";
}
if ($post_count > 2) {
$postPlural = "s";
}
echo "<tr><td>" . $post_count . " post" . $postPlural . ".";
?>
I'll apologize now for the formatting, I was trying to separate it to troubleshoot.
Any help to get this working would be greatly appreciated.
There are many ways to search files.
use preg_match_all function to match pattern for each file.
use system() function to run external command like grep (only available under *nix).
use strpos function ( not recommended because of low performance and lack of support of pattern ).
If you will face a big traffic you'd better use pre-build indexes to accelerate the search. for example split the posts into tokens ( words ) and add position info along with the words, when user search the some words you can just split the words first and then look for the indexes. It's simpler to discribe this method than to implement it. You may need a existing full-text search engine like Apache Lucene.

How would I link to thumbnails in a subdirectory, when using php to get a list of images?

I'm sorry if the title is a little vague ... I'm still relatively new at PHP (3 months or so) Also, my native tongue is not English, so please bear with me :) I have also searched this site and google extensively to try and find a solution, but without any luck.
I have a script set up in my images directory that scans all the subdirectories, and then outputs a list of links that, if clicked, will take you to a page, where all the images of the selected subdirectory are displayed. The path to such a page would be:
www.mysite.com/images/list_images.php?folderName=RandomFolder
The code for this:
images/index.php
<?php
$path = 'images/' ;
$results = scandir($path);
for ($i=0;$i<count($results);$i++)
{
$result=$results[$i];
if ($result === '.' or $result === '..')
continue;
if (is_dir($path . '/' . $result))
{
echo "<a href='list_images.php?folderName=$result'>$result</a><br/>";
}
}
?>
--------------------
list_images.php
<?php
if(isset($_GET['folderName']))
$folder=$_GET['folderName'];
$path = 'images/'.$folder.'/' ;
$images = glob($path . '*.{jpg,jpeg,png,gif}', GLOB_BRACE);
foreach ($images as $image)
{
echo "<a href='$image'><img src='$image'/></a>";
}
?>
Now, my question:
In each of my image subdirectories I have another subdirectory called 'thumbs', that contains - yes, you guessed it - thumbnails. Each thumbnail is named exactly the same as its corresponding file in the directory above it. Now, how would I make the img src in the above code to point to the thumb?
Any help would be very welcome! Thank you in advance!
EDIT:
I looked over my code again, and I made few extra lines. It still doesn't work, but at least it now outputs thumbnails, which links to the larger image. Here's the new code:
list_images.php
if (isset($_GET['folderName'])) $folder=$_GET['folderName'];
$path = 'images/'.$folder.'/' ;
$thumb_path = ''.$path.'/thumbs/';
$thumbs = glob($thumb_path . '*.{jpg,jpeg,png,gif}', GLOB_BRACE);
$images = glob($path . '*.{jpg,jpeg,png,gif}', GLOB_BRACE);
foreach ($thumbs as $thumb){
foreach ($images as $image){
echo "<a class='fancybox' href='$image'><img src='$thumb'/></a>";
}
}
It kinda works now. The only problem is, that it outputs 13 identical thumbnails to each picture - and it does it 13 times (for a directory containing 13 image files) so there is 169 thumbnails in total.
Any ideas how to fix this?
If you are sure that the folder name is thumbs, there is no reason you can't hardcode this. Take a look at the following.
echo "<a href='$image'><img src='thumbs/$image'/></a>";
You could do a str_replace on the path.
If the path to the image is mydir\image01\pic01.jpg
str_replace('image01','image01\thumb',$image);
would point to mydir\image01\thumb\pic01.jpg

Using php to get parent element of link with URL

I'm trying to implement a "find and replace" system for broken links. The problem is, for some links there are no replacements. So, I need to comment out certain li elements. You can see my code below to do this. (I'm starting with an HTML form).
<?php
$brokenlink = $_POST['brokenlink'];
$newlink = $_POST['newlink'];
$brokenlink = '"' . $brokenlink . '"';
$newlink = '"' . $newlink . '"';
$di = new RecursiveDirectoryIterator('hugedirectory');
foreach (new RecursiveIteratorIterator($di) as $filename => $file) {
// echo $filename . ' - ' . $file->getSize() . ' bytes <br/>';
$filetoedit = file_get_contents($file);
if(strpos($filetoedit, $brokenlink)) {
echo $brokenlink . "found in " . $filename . "<br/>";
$filetoedit = str_replace($brokenlink, $newlink, $filetoedit);
file_put_contents($filename, $filetoedit);
}
}
?>
What I want to accomplish is this: If I have a URL, I want to be able to find its li parent. For instance, I want PHP to be able to comment out the code below if the user inputs http://www.espn.com in an HTML form, I want php to find this element on my server:
<li>Sports</li>
And replace it with this:
<!-- <li>Sports</li> -->
Is this possible? Thanks.
I would try using this to parse the DOM.
http://simplehtmldom.sourceforge.net/
You can set a class to all the ones you want comment out. Then use this tool to find those classes and comment them all out at once.
Why not use a regexp to find and replace links, it would also take care of the perhaps expensive looping over links.
Here's a regex for matching urls
http://daringfireball.net/2010/07/improved_regex_for_matching_urls
then preg_replace the broken with the new, or the broken with the commented out version of the broken link
Alternatively you can just run grep on the directory via shell_exec, that way you don't have to open / read and parse files yourself.
Also take a look at this match url pattern in php using regular expression
I suggest you construct DOMDocument with the file content and use XPath to search for the broken link node.
$dom = new DOMDocument();
#$dom->loadHTML($filetoedit);
$xpath = new DOMXPath($dom);
$nodes = $xpath->query('//li/a[#href="' . $brokenlink . '"]');
for ($i = 0; $i < $nodes->length; $i++) {
$node = $nodes->item($i);
// Do whatever you want here
}

PHP help for a beginner. Scanning file structure to return folder names in an array

I am looking for some help with my code, I have looked elsewhere but am having difficulty to really understand what is going on with the code given elsewhere and I am hoping someone can help me.
I have one gallery page that uses $_POST to change the folder the gallery gets it images form based on the link clicked.
What I want now is to code a search function that looks through them all for a string (a jpg) when it finds it, it returns its img tags and displays the image.
I am having trouble making scandir work and display currently using this code
<?php
$dir = "/galleries/images/adult-cakes/images/";
$scan = scandir($dir);
echo $dir;
print_r($scan);
foreach ($scan as $output) {
echo "$output" . "<br />";
}
?>
that returns the echo dir but nothing else ( please note print was something I tried it was echo before and neither is working.
Then I need to get the output of all the gallery types, adult, anniversary etc and put them into a loop like so
search criteria = cake 1(.jpg)
put scandir info into $folderarray
search this folder until found -
galleries/images/$folderarray/images/
loop
if found then echo img tags with link to pic
if not display not found
This will get an array of all the files in directory $dir
<?php
$dir = "/galleries/images/adult-cakes/images/";
$images = glob($dir . '*');
?>
Do this to get all subdirectories of $Dir into array $DirArray:
$Dir = '/galleries/images/'; //
foreach ( $DirArray = array_filter(glob($Dir . '*'), 'is_dir') as $DirName ) {
$DirName = str_replace($Dir, '', $DirName); // Optionally, remove path from name to display
echo "Dir Name: $DirName <br />\n"; // Test
}
echo var_dump($DirArray); // Test
Modify accordingly

display random images without repetition

My name is Shruti.I'm new to php. I have a program which displays images randomly, there are about 200 images in my program.I want to display the random images with out repetition, can any one please help with this. here is my code.
Appreciate your help
Thank you.
I don't know whats about the $img_id but you could consider to use shuffle().
shuffle($file_array);
But then you loose the connection to $img_id. You could (I am not sure if this is the best solution), build your array this way:
$file_array = array(
array("images/bag200.bmp", 1),
array("images/bag178.bmp", 1),
array("images/bag004.bmp", 0,
...
);
In the long run, it is probably better to store all the image paths in a CSV file or even a database. Believe me, you don't want to maintain an array with > 200 entries manually ;)
You can loop over images this way (they are in random order now):
<?php foreach($file_array as $image): ?>
<img src="<?php echo $image ?>" />
<?php endforeach; ?>
If you only want to display a subset of the images, randomly chosen, you can do this:
$n = 20; // want to display 20 images
$rand = array_rand(range(0,200), $n); // draw keys randomly
shuffle($rand); //shuffle keys
foreach($rand as $r) {
echo '<img src="' . $file_array[$r] . '" />';
}
Some comments on your code:
$ran = array_rand($file_array);
$ran contains a key randomly chosen from the images.
for ($i=0;$i<200;$i++) {
//while (in_array($tst,$rand_array)){
$tst = $file_array[$ran];
$id = $img_id[$ran];//}
$rand_array[] = $tst;
$rand_id[] = $id;
}
You always pick the same entry from $file_array and $image_id because you never change $ran. That is way you get the same image 200 times.
If you want randomness but require uniqueness, you are looking for a quasi-random number generator. There are many different types with different properties. Look here for information on creating an algorithm: http://www.mathworks.nl/access/helpdesk/help/toolbox/stats/br5k9hi-8.html

Categories