Getting the actual document root in PHP? - php

I'm not sure exactly where this script will be running, so it must be able to access this directory from anywhere.
I'm trying to create a list of images by getting the image file names from a directory, filtering them until I only have the image formats I want, then displaying them using an <img> tag.
The first bit went really well. Outputting the HTML is proving to be a problem.
While I can use $_SERVER["DOCUMENT_ROOT"] to work with the directories in PHP, it's problematic to output that value as part of the path in thetag'ssrc` attribute.
Here is my current code:
$unkwown_files = scandir($_SERVER['DOCUMENT_ROOT'] . "/path/images");
foreach($unkwown_files as $file) {
$exploded_filename = explode(".", $file);
$file_type = array_pop($exploded_filename);
$accepted_filetypes = [
"png",
"jpg",
"gif",
"jpeg"
];
$picture_names = [];
if (in_array($file_type, $accepted_filetypes)) {
$picture_names[] = $file;
}
}
foreach($picture_names as $picture) {
$path_to_image = $_SERVER['DOCUMENT_ROOT'] . "/nodes/images" . $picture;
echo '<img src="' . $path_to_image . '" class="upload_thumbnail"/>';
}

A slightly different approach for you that filters files by extension from the outset.
$dir = $_SERVER['DOCUMENT_ROOT'] . "/path/images/";
/*
glob() searches for files/paths that match the pattern in braces and returns the results
as an array.
The '*' is a wildcard character as you would expect.
The flag 'GLOB_BRACE' expands the string so that it tries to match each
( From the manual: GLOB_BRACE - Expands {a,b,c} to match 'a', 'b', or 'c' )
*/
$col = glob( $dir . "*.{jpg,png,gif,jpeg}", GLOB_BRACE );
/*
Iterate through the results, with each one being the filepath to the file found.
As the glob() function searched for the required types we don't need to check
if they are in the allowed types array.
Because you do not wish to display the fullpath to the image, a relative path is
preferred - thus we remove, from the path, the document root.
*/
foreach( $col as $index => $file ){
$path_to_image = str_replace( $_SERVER['DOCUMENT_ROOT'], '', $file );
echo '<img src="' . $path_to_image . '" class="upload_thumbnail"/>';
}

Try this out
foreach($picture_names as $picture) {
$path_to_image = $_SERVER['DOCUMENT_ROOT'] . "/nodes/images/" . $picture;
echo '<img src="' . $path_to_image . '" class="upload_thumbnail"/>';
}

Related

using 'glob' to get all images from a directory

I'm trying to get all images from a directory and print them. I know my URL is correct because I am echoing the the $dirname along with a .jpg image I have saved in the directory. What am I doing wrong?
<?php
$dirname = "uploads/{$site_country}_{$site_state}_{$site_name}/{$record_id}/";
$images = glob($dirname . "*.jpg");
foreach($images as $image) {
echo '<img src="'.$image.'"/>';
}
//check to see if $dirname is correct
echo '<img src="' . $dirname . "IMG_0002.JPG" . '"/>';
?>
//edit
I have solved my problem, by removing the jpg extention and just pulling "*" for everything in the folder. Although it works for me now, its not best practice. It must be something to do with different .jpg file formats?
You used lowercase file extension here.
$images = glob($dirname . "*.jpg");
And uppercase JPG in your test output.
echo '<img src="' . $dirname . "IMG_0002.JPG" . '"/>';
If you're using a linux system then file extensions are case sensitive.
You need to prepend the dirname to glob's result to get the full paths.
So something like:
$dirname = "uploads/{$site_country}_{$site_state}_{$site_name}/{$record_id}/";
$images = glob($dirname . "*.jpg");
foreach($images as $image) {
echo '<img src="'.$dirname.$image.'"/>';
}

getting directory of a file without knowing its extension

I want to be able to present the photo of a user. That user may be of the type Doctor, Nurse or Patient and each person belonging to each of those types has a distinct ID which identifies him. I have the photos of each type of users separated in three folders inside the directory /images/user_upload/ and a given user may or may not have a photo. If he has a photo, I want to present the photo with a name which is the same as his ID (Note that I don't know the extension of this file, only the name). If he doesn't I want to present a default image. I have a function called printUserPhoto for this end.
function printUserPhoto()
{
$path = '/images/user_upload/' .ucfirst($_SESSION['listtype']). '/' .$_SESSION['id']. '.*';
$source = glob($path);
if(empty($source))
echo '<img src="images/default_profile_img.png" />';
else
echo '<img src="',$source[0],'" />';
}
Although, I always get an empty array in the variable $source, even though the image exists. What am I doing wrong?
This way with glob
function printUserPhoto()
{
$pathToDocumentRoot = $_SERVER['DOCUMENT_ROOT'];
$path = $pathToDocumentRoot . '/images/user_upload/' .ucfirst($_SESSION['listtype']). '/' .$_SESSION['id']. '.*';
$source = glob($path);
if(empty($source)){
echo '<img src="images/default_profile_img.png" />';
} else {
echo '<img src="',$source[0],'" />';
}
}
Maybe limit the filetypes user can upload. With that you could do something like this:
function printUserPhoto()
{
$pathToDocumentRoot = $_SERVER['DOCUMENT_ROOT'];
$path = $pathToDocumentRoot . '/images/user_upload/' .ucfirst($_SESSION['listtype']). '/' .$_SESSION['id'];
$file = "images/default_profile_img.png";
if(file_exists($path . '.jpg')){
$file = $path . '.jpg';
}else if(file_exists($path . '.png')){
$file = $path . '.png';
}else if(file_exists($path . '.gif')){
$file = $path . '.gif';
}
echo '<img src="' . $file . '" />';
}
Also as being said by #Phil you are now referring to the file system root / being absolute path not relative to your document root.

Paginate files in a directory

I have a directory with almost 60 images but in HD quality so theirs size are around 5 ~ 6 MB and load all them in a web page is to much time for server and browser so both hang up. I read this post and this other too and since I'm using PHP 5.4.20 in my server I'll like to use DirectoryIterator and LimitIterator but example leave in the post are not so explicit to me since I don't know how to move forward/backward in this cases. Can any give me some sample code about paginate files in a directory?
UPDATE: show some code
Right now this is how I read files:
function directoryToArray($directory, $recursive) {
$array_items = array();
if ($handle = opendir($directory)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
if (is_dir($directory . "/" . $file)) {
if ($recursive) {
$array_items = array_merge($array_items, directoryToArray($directory . "/" . $file, $recursive));
}
$file = $directory . "/" . $file;
$array_items[] = preg_replace("/\/\//si", "/", $file);
} else {
$file = $directory . "/" . $file;
$array_items[] = preg_replace("/\/\//si", "/", $file);
}
}
}
closedir($handle);
}
return $array_items;
}
$images = directoryToArray("images/portfolio/");
for ($i = 0; $i < count($images); $i++) {
$old_img_name = explode('/', $images[$i]);
$new_img_name = $old_img_name[0] . "/" . $old_img_name[1] . '/large/' . $old_img_name[2];
echo '<div class="span4 element">';
echo '<div class="hover_img">';
echo '<img src="' . $images[$i] . '" alt="" />';
echo '<span class="portfolio_zoom"></span>';
echo '</div>';
echo '</div>';
}
Aristona's absolutely right. You should probably resize the images to an appropriate file-format, quality & size. At the very least if you're trying to make some sort of gallery, you could use something like image magick to make 'thumbnails' for the gallery where clicking on them may take you to the full-quality image.
Image magick is scriptable in a variety of languages to batch process your images and build thumbnails if you want it to run as a process, alternatively from the command line you can do it as a once off, something like what's mentioned here:
Batch resize images into new folder using ImageMagick

List images(01.png) and descriptions(01.txt) from directory

How can I display images from directory and get a corresponding description with each image, give the description exists.
in Directory //
01.png
01.txt
02.png
03.png
03.txt
etc.
to display as //
<img src="01.png"><br>This is the description from the text file named 01.txt
<img src="02.png"><br>
<img src="03.png"><br>This is the description from the text file named 03.txt
I've been searching and searching, but can't find anything, so if someone could point me in the right direction it would be greatly appreciated. Also this is a very useful thing to be able to do for people wanting to create very simple galleries or lists of images and names.
Thanks in advance!
This is what you're looking for, as the description must be dynamically captured from a corresponding .txt file:
$dir = './';
$files = glob( $dir . '*.png');
foreach( $files as $file) {
$filename = pathinfo( $file, PATHINFO_FILENAME) . '.txt';
$description = file_exists( $filename) ? file_get_contents( $filename) : '';
echo '<img src="' . $file . '"><br>' . $description;
}
What it does is grabs an array of *.png files using glob() from a given directory ($dir). Then, for each image, it gets the filename of the image (so 01.png would be 01), and appends .txt to get the name of the description file. Then, it loads the description file into the $description variable using file_get_contents() if the description file exists. It then outputs the desired HTML.
I assume you have the .php file in the same directory as the pictures and text files are.
You could use function glob() to read in all image-files as array from the directory, cut off the file extension (so '01.png' becomes '01') and append the file extension with string concatentation.
A working code example may look like this:
<?php
$path_to_directory = './';
$pics = glob($path_to_directory . '*.png');
foreach($pics as $pic)
{
$pic = basename($pic, '.png'); // remove file extension
echo '<img src=\"{$pic}.png\"><br>';
if(file_exists($pic . '.txt'))
{
echo file_get_contents("{$pic}.txt");
}
}
?>
So definitely have a look on these functions:
http://www.php.net/glob
http://www.php.net/basename
http://www.php.net/file_get_contents
Happy coding.
Your question is a bit confusing.
make an array with all information.
$pics = array('img' => '01.png', 'text' => 'This is the description');
foreach($pics as $pic) {
echo '<img src="'.$pic['name'].'" alt="">' . $pic['text'];
}
So you have to put your information in an array or a database otherwise you cannot map the desciption to your image.
When you want to read dynamicly the folder its a bit difficult.
You can look at readdir or glob then you can read all images get the name and load the textfile with file_get_contents but i think its not a really performant way.
Code Modified from here : http://php.net/manual/en/function.readdir.php
//path to directory to scan
$directory = "../images/team/harry/";
//get all image files with a .jpg extension.
$images = glob($directory . "*.jpg");
//print each file name
foreach($images as $image)
{
print "<img src=\"$image\"><br>This is the description from the text file named $image";
}
ok, so this won't print the contents of the text file, but I'm sure you can further modify the code above to figure that out
YEP
Updated version of ZnArKs code, as he missed that you wanted the content of the files
//path to directory to scan
$directory = "../images/team/harry/";
//get all image files with a .jpg extension.
$images = glob($directory . "*.png");
//print each file name
foreach($images as $image)
{
$textfile = substr($image, 0, -3) . "txt";
echo "<img src='{$image}'><br/>";
if(file_exists($textfile))
{
echo file_get_contents($textfile) . "<br/>";
}
}

PHP strrchr find the next to the last not the last ocurrence

I was using the strrchr PHP function with substr and strrpos to find the file name in a string with the full path like:
/images/onepiece.jpg returns
onepiece.jpg
but now I need to a function to find not the last "/" but the one next to the last:
/images/anime/onepiece.jpg returning anime/onepiece.jpg or /anime/onepiece.jpg
And as strrchr - 1 doesn't work, hehehe :), how can I achieve that?
[SOLVED]
Using PHP pathinfo() as #middaparka and #Shakti Singh said, I've change the way I get the image string from the MySQL database. Now it can have subfolders, as was my initial intention.
<?php
/*
* pathinfo() parameters:
* PATHINFO_DIRNAME = 1
* PATHINFO_BASENAME = 2
* PATHINFO_EXTENSION = 4
* PATHINFO_FILENAME = 8
* */
$slash = '/';
$mainpath = 'store/image/';
$thumbspath = 'cache/';
$path = $imgsrow->photo; //gets the string containing the partial path and the name of the file from the database
$dirname = pathinfo($path, 1); //gets the partial directory string
$basename = pathinfo($path, 2); //gets the name of the file with the extension
$extension = pathinfo($path, 4); //gets the extension of the file
$filename = pathinfo($path, 8); //gets the name of the file
$dims = '-100x100.'; //string of size of the file to append to the file name
$image = $mainpath . $path; //mainpath + path is the full string for the original/full size file
$thumbs = $mainpath . $thumbspath . $dirname . $slash . $filename . $dims . $extension; //string to point to the thumb image generated from the full size file
?>
<img src="<?= $thumbs; ?>" width="100" height="100" alt="<?= $row->description; ?>" />
<br />
<img src="<?= $image; ?>" width="500" height="500" alt="<?= $row->description; ?>" />
To be honest, it would be a lot easier to use the pathinfo or dirname functions to decompose directory paths.
For example:
$filename = pathinfo('/images/onepiece.jpg', PATHINFO_BASENAME);
$directory = dirname('/images/onepiece.jpg');
You may have to use a mix of these to obtain what you're after but they will at least be OS "safe" (i.e.: will handle both Linux/Linux and Windows path styles).
In terms of the specific problem you have, you should be able to use the following cross-platform solution to get what you need:
<?php
$sourcePath = '/images/anime/onepiece.jpg';
$filename = pathinfo($sourcePath, PATHINFO_BASENAME);
$directories = explode(DIRECTORY_SEPARATOR, pathinfo($sourcePath, PATHINFO_DIRNAME));
echo $directories[count($directories) -1] . DIRECTORY_SEPARATOR . $filename;
?>
I would suggest to use explode to split the path into its segments:
$segments = explode('/', $path);
Then you can use $segments[count($segments)-1] to get the last path segment.
And for for last two segments you can use array_slice with implode to put them back together:
$lastTwoSegments = implode('/', array_slice($segments, -2));
you need to use pathinfo function
pathinfo ($path, PATHINFO_FILENAME );
Dude, just make a temp string to hold the string you want to find. Find the last occurrence, replace it with something, like x, and then find the new last occurrence, which is the second to last occurrence.

Categories