Read file one by one from a directory - php

I am developing an application using php for personal use. What I want to achieve is :
I have a large number of images in a directory. I want to write some description for every image. I have prepared a DB table with 3 columns : id, image_name(unique constraint) and description.
And to make it work, I have developed a webpage, where I would open each image in the browser, write a description about it, save to the database and then open the next image by clicking next and so on.
However, I couldn't figure out how to achieve it. If I do something like :
$dir = "/images/";
// Open a directory, and read its contents
if (is_dir($dir)){
if ($dh = opendir($dir)){
while (($file = readdir($dh)) !== false){
echo "filename:" . $file . "<br>";
}
closedir($dh);
}
}
Then I would end up opening n-1 images always , before I reach the nth image.

I would first import the files into the database. Not the actual files , but just a reference to the file in the folder.
(this is not the complete code, but you'll get the point)
$files = array_diff( scandir("/path/to/directory"), array(".", "..") );
foreach($files as $file) {
//insert a reference into the database
$query = "insert into table_name (image_name) values $file;";
mysql_query($query);
}
Once they are in place you can easily query them by the Id.
A webpage would look something like this:
<?php
$imageId= (int)$_GET['id'];
$row = mysql_fetch_array("select * from table_name where id=$imageId");
?>
<html><body>
Next image
<img src="<? echo $row['image_name']; ?> ">
your form here...
and go to your page using for example http://127.0.0.1/images/index.php?id=1

Using browser you cannot do it because between web requests PHP does not keep its state.
What you can do is:
Keep the last image number in a cookie - on next request you will read it and skip to the desired number (you still have to skip).
Send the whole list of files from PHP to your browser and navigate through it within one page using Javascript and AJAX requests.
Keep the list and/or the current number in your database in some temporary table. So each time you send the request to PHP script, it will first check if saved data exists.

What I would do is to find an image that doesn't exist in the database already and request a description for it, this would make the php to be like:
if (!empty($_POST['image'])) {
// Save the image / description in the db
}
$existing = array(); // Fill this array with the image names that exist in the db.
$dir = "/images/";
// Open a directory, and read its contents
$file = null;
if (is_dir($dir)){
if ($dh = opendir($dir)){
while (($file = readdir($dh)) !== false){
if (!in_array($file, $existing)) {
break;
}
}
closedir($dh);
}
}
if ($file === null) {
die('something is wrong, I can not get any files');
}
// set the $file to your view
And in the html I would have something like this:
<form action="">
Image: <input name="image" type="text" value="<?php echo $file; ?>"/>
Description: <input name="description" type="text" value="<?php echo $file; ?>"/>
</form>

Related

How to rerun php on page reload, for an image rotator [duplicate]

This question already has answers here:
How to prevent Browser cache for php site
(7 answers)
Closed 3 years ago.
I am trying to give my wordpress site a randomly pulled "About the Author" image in my footer.
My first solution was to create an array, name them each aboutAuthor[x].jpg and generate a random number for x.
That works just fine, but I was looking for a solution that didn't involve me having to rename files and adding a line of code every time I decide to add a new image to the folder.
I found a solution on this site: http://photomatt.net/scripts/randomimage
He provides some php code
<?php
$folder = '';
$exts = 'jpg jpeg png gif';
$files = array();
$i = -1;
if ('' == $folder)
$folder = './';
$handle = opendir($folder);
$exts = explode(' ', $exts);
while (false !== ($file = readdir($handle))) {
foreach ($exts as $ext) {
if (preg_match('/\.' . $ext . '$/i', $file, $test)) {
$files[] = $file;
++$i;
}
}
}
closedir($handle);
mt_srand((double) microtime() * 1000000);
$rand = mt_rand(0, $i);
header('Location: ' . $folder . $files[$rand]);
?>
Then I simply place that php file in the directory in question and call it in place of an image
<img src="/imgDirectory/rotate.php">
The only problem with this is that my browser is caching the resulting random image.
With a normal reload or clicking a link to a new page, I get the same image.
With a hard reload, I get a new one, like I want.
Oddly, in the sample on his website, it works as expected with a normal reload.
So what is the best way to achieve what I'm looking for?
Here is the solution
1) Create new div:
<div class="randomAuthor" id="randomAuthor"> </div>
2) Move image source
<img src="/imgDirectory/rotate.php">
to a separate PHP or html file, example author.php:
3) Load author.php into div "randomAuthor" using
ajax code:
$(document).ready(function(){
$('#randomAuthor').load("author.php");
});
This way on each refresh the $(document).ready(function(){..... will get triggerd which in turn will trigger rotate.php file thus you will get new image each time you open your page or refresh it.

open file on client stored on server

I want to open a server stored html report file on a client machine.
I want to bring back a list of all the saved reports in that folder (scandir).
This way the user can click on any of the crated reports to open them.
So id you click on a report to open it, you will need the location where the report can be opend from
This is my dilemma. Im not sure how to get a decent ip, port and folder location that the client can understand
Here bellow is what Ive been experimenting with.
Using this wont work obviously:
$path = $_SERVER['DOCUMENT_ROOT']."/reports/saved_reports/";
So I though I might try this instead.
$host= gethostname();
$ip = gethostbyname($host);
$ip = $ip.':'.$_SERVER['SERVER_PORT'];
$path = $ip."/reports/saved_reports/";
$files = scandir($path);
after the above code I loop through each file and generate a array with the name, date created and path. This is sent back to generate a list of reports in a table that the user can interact with. ( open, delete, edit)
But this fails aswell.
So im officially clueless on how to approach this.
PS. Im adding react.js as a tag, because that is my front-end and might be useful to know.
Your question may be partially answered here: https://stackoverflow.com/a/11970479/2781096
Get the file names from the specified path and hit curl or get_text() function again to save the files.
function get_text($filename) {
$fp_load = fopen("$filename", "rb");
if ( $fp_load ) {
while ( !feof($fp_load) ) {
$content .= fgets($fp_load, 8192);
}
fclose($fp_load);
return $content;
}
}
$matches = array();
// This will give you names of all the files available on the specified path.
preg_match_all("/(a href\=\")([^\?\"]*)(\")/i", get_text($ip."/reports/saved_reports/"), $matches);
foreach($matches[2] as $match) {
echo $match . '<br>';
// Again hit a cURL to download each of the reports.
}
Get list of reports:
<?php
$path = $_SERVER['DOCUMENT_ROOT']."/reports/saved_reports/";
$files = scandir($path);
foreach($files as $file){
if($file !== '.' && $file != '..'){
echo "<a href='show-report.php?name=".$file. "'>$file</a><br/>";
}
}
?>
and write second php file for showing html reports, which receives file name as GET param and echoes content of given html report.
show-report.php
<?php
$path = $_SERVER['DOCUMENT_ROOT']."/reports/saved_reports/";
if(isset($_GET['name'])){
$name = $_GET['name'];
echo file_get_contents($path.$name);
}

Randomize full-screen background image in WordPress

I haven't seen this asked yet, so if it is, can someone re-direct me?
I'm having an issue creating a full screen background for my WordPress theme that uses random images from the image library. I want to write a PHP function that can be used on multiple sites, so I can't simply use the direct path in the code. It also needs to work on MultiSite in such a way that it only pulls images that are uploaded to that site. Here's the code I'm working with:
HTML for my Background Div
<div id="background" class="background" style="background-image:url(<?php displayBackground();?>);">
</div>
PHP to randomize my image folder
<? php
function displayBackground()
{
$uploads = wp_upload_dir();
$img_dir = ( $uploads['baseurl'] . $uploads['subdir'] );
$cnt = 0;
$bgArray= array();
/*if we can load the directory*/
if ($handle = opendir($img_dir)) {
/* Loop through the directory here */
while (false !== ($entry = readdir($handle))) {
$pathToFile = $img_dir.$entry;
if(is_file($pathToFile)) //if the files exists
{
//make sure the file is an image...there might be a better way to do this
if(getimagesize($pathToFile)!=FALSE)
{
//add it to the array
$bgArray[$cnt]= $pathToFile;
$cnt = $cnt+1;
}
}
}
//create a random number, then use the image whos key matches the number
$myRand = rand(0,($cnt-1));
$val = $bgArray[$myRand];
}
closedir($handle);
echo('"'.$val.'"');
}
I know that my CSS markup is correct because if I give the DIV a fixed image location, I get a fullscreen image. Can anyone tell me what to do to fix it?

Selecting file to be edited

i have an application that is used to edit .txt files. the application is made up of 3 parts
Displays contents of a folder with the files to be edited(each file is a link when clicked it opens on edit mode).
writing in to a file.
saving to file.
part 2 and 3 I have completed using fopen and fwrite functions that wasn't too hard. the part that i need help is part one currently I open the file by inputing its location and file name like so in the php file where i have the display function and save function:
$relPath = 'file_to_edit.txt';
$fileHandle = fopen($relPath, 'r') or die("Failed to open file $relPath ! ");
but what i want is for the file to open in edit mode when clicked instead of typing in the files name every time.
$directory = 'folder_name';
if ($handle = opendir($directory. '/')){
echo 'Lookong inside \''.$directory.'\'<br><br>';
while ($file = readdir($handle)) {
if($file !='.' && $file!='..'){
echo '<a href="'.$directory.'/'.$file.'">'.$file.'<a><br>';
}
}
}
this is the code that ti use to display the list of files that are in a specified folder.
Can anyone give me some pointers how I can achieve this ? any help will be greatly appreciated.
To get content of file use file_get_contents();
To put content of file use file_put_contents(); with FILE_APPEND flag for editing.
To recieve list of files in directory you can use DirectoryIterator
Example:
foreach (new DirectoryIterator('PATH/') as $fileInfo) {
if($fileInfo->isDot()) continue;
echo $fileInfo->getFilename() . "<br>\n";
}
If you don't want to put filenames you can put read files once put in db assign ids to them and use links with id param. The other solution is to store files in session array and assign keys for them. When you want to get a file you just need to provide key instead of whole filename and path.
Example with $_SESSION
$file_arr = array();
foreach (new DirectoryIterator('PATH/') as $fileInfo) {
if($fileInfo->isDot()) continue;
$file_arr[] = array("path" => $fileInfo->getPathname(), 'name' => $fileInfo->getFilename());
}
$_SESSION['files'] = $file_arr;
then in view you can use
foreach($_SESSION['files'] as $k=>$file)
{
echo "<a href='edit.php?f=".$k."'>'.$file['name'].'</a>";
}
and edit.php
$file = (int)$_GET['f'];
if(array_key_exits($file, $_SESSION['files'])
{
$fileInfo = $_SESSION[$file'];
//in file info you have now $fileInfo['path'] $fileInfo['name']
}

Changing the names of images within a directory and displaying the changed file names

The purpose of the script is to change the names of of a list of images within a directory for an ecommerce site. So specifically when the script is rand a user will type in a word or phrase that they would like a set or list of files to be prefixed with. The script will iterate over each file changing the prefix and appending the next available number starting from zero.
I'd like to display/render on the page to the user what files have been changed. right now when the script is ran it displays the current files within the directory, and then it list the changed files and their names within the directory.
How can i get the file list only to display when the script has finish processing the new names?
Why does the script not append the proper incremented number to the file name? It renames files the following order:
abc0.jpg
abc1.jpg
abc10.jpg
abc11.jpg
abc12.jpg
abc13.jpg
<?php
$display_file_list;
//Allow user to put choose name
if (isset($_POST['file_prefix'])){
$the_user_prefix = $_POST['file_prefix'];
//open the current directory change this to modify where you are looking
$dir = opendir('.');
$i=0;
//Loop though all the files in the directory
while(false !==($file = readdir($dir)))
{
//This is the way we would like the page to function
//if the extention is .jpg
if(strtolower(pathinfo($file, PATHINFO_EXTENSION)) =='jpg')
{
//Put the JPG files in an array to display to the user
$display_file_list[]= $file;
//Do the rename based on the current iteration
$newName = $the_user_prefix.$i . '.jpg';
rename($file, $newName);
//increase for the next loop
$i++;
}
}
//close the directory handle
closedir($dir);
}else{
echo "No file prefix provided";
}
?>
<html>
<body>
<form action="<?=$_SERVER['PHP_SELF']?>" method="POST">
<input type="text" name="file_prefix"><br>
<input type="submit" value="submit" name="submitMe">
</form>
</body>
</html>
<?php
foreach ($display_file_list as $key => $value) {
echo $value. "<br>";
}
?>
"How can i get the file list only to display when the script has finish processing the new names?"
I think this will work for you;
$path = "path/to/files";
$files = glob("{$path}/*.jpg");
$files_renamed = array();
foreach ($files as $i => $file) {
$name = "{$path}/{$prefix}{$i}.jpg";
if (true === rename($file)) {
$files_renamed[] = $name;
}
}
print_r($files_renamed);

Categories