I am trying to get my code to work. I basically check that if a folder exists, and any sub folder exists within that directory called 3 or more (3,4,5) then do a loop, otherwise nothing.
// the folder path
$folderPath="".cdnurl."assets/".pid."";
// looks like site.com/assets/342/
// is there a sub folder called 3 or more, 3,4,5 and loop from 3
// site.com/assets/342/3
// site.com/assets/342/4
// etc, we only loop if 3 exists other wise nothing
$folderSubNumber =>3;
while(file_exists($folderPath.$folderSubNumber)) {
echo '<li><img src="assets/pid/'.folderSubNumber.'';
} else {
// nothing
echo "";
}
It looks like what you have should do it. Just change that => to a simple =, and don't forget to increment:
while (file_exists($folderPath.$folderSubNumber)) {
echo '...';
$folderSubNumber += 1;
}
(Also, the else part isn't allowed. But you don't need it here, so nothing lost.)
A simple method:
$subdirs = glob(cdnurl . "assets/" . pid . "/*", GLOB_ONLYDIR);
that'll return all subdirectories in the specified directory. Ref: http://php.net/glob
Prepare for some constructive criticism, please.
There's a lot wrong with this code. First I'll add comments to explain some of the mistakes as well as some of the pointless things that do nothing.
$folderPath="".cdnurl."assets/".pid."";
// 1. Single-quotes will perform slightly better.
// 2. There is no need for the first "". or the final ."" - they do nothing.
// 3. Ideal: $folderPath = cdnurl.'assets/'.pid;
// 4. This assumes that cdnurl and pid are constants declared with the define() command. If they are not constants, you need dollar-signs, which would make it:
// $folderPath = $cdnurl.'assets/'.$pid;
$folderSubNumber => 3;
// You cannot put a "more than X" or "less than X" in a variable. The => is used in foreach() loops for a completely different purpose, and when declaring values in an array only when the array is originally declared. (In other words; in this case, this does nothing.)
// Indentation really does matter. This should be indented the same as the code above.
while(file_exists($folderPath.$folderSubNumber)) {
// 1. $folderSubNumber never changes and so this while-loop always asks the exact same question.
// 2. You don't have a directory separator "/", so this will append $folderSubNumber straight to pid, above.
echo '<li><img src="assets/pid/'.folderSubNumber.'';
// 1. folderSubNumber needs a dollar-sign because it's a variable. If it is not defined as a constant, it will simply be the literal string "folderSubNumber".
// 2. The appended .'' does nothing and shouldn't be there.
// 3. You are neither closing the <img> tag, nor the <li> tag, nor in fact the src-attribute.
// 4. Ideal: echo '<li><img src="assets/pid/'.$folderSubNumber.'" /></li>';
} else {
// 1. There is no "else" in while.
// 2. You don't need an "else" if the intention is to do nothing.
echo "";
// This is 100% pointless, it does nothing.
}
What you then need, is to increment $foldeSubNumber after you've tried it in the while-loop (see the answer by 'sdleihssirhc'). But also note that you probably need the directory separator between $folderPath and $folderSubNumber. That would be: $folderPath.'/'.$folderSubNumber
Good luck!
// Build folder path
$folder_path = cdnurl . 'assets/' . $pid . '/';
// Loop from 3 to 5
for ($i = 3; i <= 5; $i++) {
// Checking for a valid sub-directory
// Will check sub-directory e.g.: site.com/assets/342/3/
if ( is_dir($folder_path . $i . '/') ) {
// Sub-directory exists
echo $folder_path . $i;
} else {
// No Sub-directory, break out of for loop
// This is will stop PHP for looking for sub-directory 4 or 5
break;
}
}
Related
I have the following
$basename = !empty($_POST['basename']) ? $_POST['basename'] : null;
$upload_files = array(
'/usr/path/to/dir/' . $basename,
'/usr/path/to/dir/thumbs/' . $basename
Later on, I reassigned the variable $basename, like so
$basename = 'test.jpg';
When echo like so
echo $upload_files[0];
I want to output this
'/usr/path/to/dir/test.jpg'
But obviously, it doesn't.
Is there a trick with php where this is possible, like adding & before the variable or something?
Once you include $basename into a string, PHP loses all track of it as a variable, so subsequent changes have no effect. You could make the values in $upload_files into arrays, imploding them into strings when required, and making the second element a reference to $basename:
$basename = 'file1.gif';
$upload_files = array(
array('/usr/path/to/dir/', &$basename),
array('/usr/path/to/dir/thumbs/', &$basename)
);
echo implode('', $upload_files[0]) . PHP_EOL;
$basename = 'test.jpg';
echo implode('', $upload_files[0]). PHP_EOL;
Output:
/usr/path/to/dir/file1.gif
/usr/path/to/dir/test.jpg
Demo on 3v4l.org
What is your intended use case? If you need to access each pic string, you can store them in an array, and just use the last entry for the 'current' item. Then you'd have access to search or process each if you needed it. You can concat as needed. I'd probably write a function for processing it.
$basenames = [];
// However you're retrieving the filename
array_push($basenames, "file.gif");
// Current file
concatPic(count($basenames)-1);
// To find what key you wants position
$fileIndex = array_search("what_you're_looking_for", $basenames);
concatPic($fileIndex); // To process a specific index
function concatPic($indexValue)
{
return / echo (whatever) "usr/path/..." . $basenames[$indexValue]
};
You can also write a foreach to do all of them at once as well, or even concatenate them before pushing to the array if you want.
I am trying to make a PHP application which searches through the files of your current directory and looks for a file in every subdirectory called email.txt, then it gets the contents of the file and compares the contents from email.txt with the given query and echoes all the matching directories with the given query. But it does not work and it looks like the problem is in the if-else part of the script at the end because it doesn't give any output.
<?php
// pulling query from link
$query = $_GET["q"];
echo($query);
echo("<br>");
// listing all files in doc directory
$files = scandir(".");
// searching trough array for unwanted files
$downloader = array_search("downloader.php", $files);
$viewer = array_search("viewer.php", $files);
$search = array_search("search.php", $files);
$editor = array_search("editor.php", $files);
$index = array_search("index.php", $files);
$error_log = array_search("error_log", $files);
$images = array_search("images", $files);
$parsedown = array_search("Parsedown.php", $files);
// deleting unwanted files from array
unset($files[$downloader]);
unset($files[$viewer]);
unset($files[$search]);
unset($files[$editor]);
unset($files[$index]);
unset($files[$error_log]);
unset($files[$images]);
unset($files[$parsedown]);
// counting folders
$folderamount = count($files);
// defining loop variables
$loopnum = 0;
// loop
while ($loopnum <= $folderamount + 10) {
$loopnum = $loopnum + 1;
// gets the emails from every folder
$dirname = $files[$loopnum];
$email = file_get_contents("$dirname/email.txt");
//checks if the email matches
if ($stremail == $query) {
echo($dirname);
}
}
//print_r($files);
//echo("<br><br>");
?>
Can someone explain / fix this for me? I literally have no clue what it is and I debugged soo much already. It would be heavily gracious and appreciated.
Kind regards,
Bluppie05
There's a few problems with this code that would be preventing you from getting the correct output.
The main reason you don't get any output from the if test is the condition is (presumably) using the wrong variable name.
// variable with the file data is called $email
$email = file_get_contents("$dirname/email.txt");
// test is checking $stremail which is never given a value
if ($stremail == $query) {
echo($dirname);
}
There is also an issue with your scandir() and unset() combination. As you've discovered scandir() basically gives you everything that a dir or ls would on the command line. Using unset() to remove specific files is problematic because you have to maintain a hardcoded list of files. However, unset() also leaves holes in your array, the count changes but the original indices do not. This may be why you are using $folderamount + 10 in your loop. Take a look at this Stack Overflow question for more discussion of the problem.
Rebase array keys after unsetting elements
I recommend you read the PHP manual page on the glob() function as it will greatly simplify getting the contents of a directory. In particular take a look at the GLOB_ONLYDIR flag.
https://www.php.net/manual/en/function.glob.php
Lastly, don't increment your loop counter at the beginning of the loop when using the counter to read elements from an array. Take a look at the PHP manual page for foreach loops for a neater way to iterate over an array.
https://www.php.net/manual/en/control-structures.foreach.php
I'm working on a php file where I want to create one or more directories with names ranging from 1 to 999 or more. I'm creating the first of all directories using the following code:
<?php
$id = '001';
mkdir($id)
?>
What I want to succeed is to automatically create a new directory using as a name the next available number (i.e. 002, 003, 004, 005 etc) either as a string or an integer. However, I really stuck and I try to use:
<?php
$id = 001;
if (file_exists($id)) {
$id = $id + 1;
mkdir($id);
}
?>
..but it doesn't work. Any ideas?
I forgot to mention that the above code is part of the if statement inside the same php code.
Several ways to do this, depending on your use case. This function may work for you:
<?PHP
function makedir($id){
if(file_exists($id)){
$id++;
makedir($id);
}else{
mkdir($id);
return true;
}
}
makedir(1);
This solution of incremented directory names is going to become ugly after a while though; you should probably find a better solution to your problem.
You could do something like this:
// Loop through all numbers.
for ($i = 1; $i <= 999; $i++) {
// Get the formatted dir name (prepending 0s)
$dir = sprintf('%03d', $i);
// If the dir doesn't exist, create it.
if (!file_exists($dir)) {
mkdir($dir);
}
}
Edit: the above was assuming you wanted to make all 999 directories. You could do the following to just append the next available number:
function createDir($dir) {
$newDir = $dir;
$num = 1;
while (file_exists($newDir)) {
$newDir = $dir.sprintf('%03d', $num++);
}
return $newDir;
}
in php we can check if file exist using
if(file_exists("destination/"))
{
condition
}
but what I wanted to do is...
for example I already have this file on my destination
hello_this_is_filename(2).doc
how would I know if there is a file in that directory having a name containing a character
hello_this_is_filename
I wanted to search that way because... if there is exists on that directory, what will I do is... renaming the file into
hello_this_is_filename(3).doc
I also need to count the existence of my search so I know what number I'm going to put like
(3), (4), (5) and so on
any help?
Use glob.
if (count(glob("destination/hello_this_is_filename*.doc"))) {
//...
}
Leveraging Marc B's suggestion and xdazz, I would do something as follows:
<?php
$files = glob("destination/hello_this_is_filename*");
if (count($files)) {
sort($files);
// last one contains the name we need to get the number of
preg_match("([\d+])", end($files), $matches);
$value = 0;
if (count($matches)) {
// increment by one
$value = $matches[0];
}
$newfilename = "destination/hello_this_is_filename (" . ++$value . ").doc";
?>
Sorry this is untested, but thought it provides others with the regexp work to actually do the incrementing...
I have a php script that checks to see if a particular file exists. This name of the file is defined by the 'compartment' variable. When the script is copied and pasted again into a separate block, changing only the compartment variable it runs into a problem...
Say for example 1.jpeg exists but 2.jpeg doesn't. The first block displays a link to this file, but so does the second block when it should be displaying the upload form as 2.jpeg doesn't exist.
It's as though the $currentfile or $filename variables are being carried over into the blocks below them.
Please find an example of my problem below...
<?php
$compartment = "1";
foreach (glob("$compartment.*") as $filename) {
$currentfile = "$filename";
}
if (file_exists($currentfile)) {
echo "
/* If the file exists, it will display a link to the file. */
<a href='$currentfile' target='_blank'>LAUNCH PREVIEW</a>
";
} else {
echo "
/* Here is an uploader form that would transform foobar.jpeg into $compartment.jpeg. */
";
}
?>
<?php
$compartment = "2";
foreach (glob("$compartment.*") as $filename) {
$currentfile = "$filename";
}
if (file_exists($currentfile)) {
echo "
/* If the file exists, it will display a link to the file. */
<a href='$currentfile' target='_blank'>LAUNCH PREVIEW</a>
";
} else {
echo "
/* Here is an uploader form that would transform foobar.jpeg into $compartment.jpeg. */
";
}
?>
Thank You.
Maybe your file_exists() must be inside of foreach otherwise $currentfile always be the last file found in the directory.
$filename isn't containing path variable
Your logic seems a little bit weird for me. You iterate through a dir and checks every file inside if file_exists or not. Because no other checking (against a prepopulated array for example) happens this will always return true.
foreach will fail to execute (and should yell at you) if you provide a non-array variable.
Therefore since 2.jpeg doesn't exist, glob() will return NULL making foreach not execute. However, you are assigning $currentfile within a foreach that never executes so $currentfile will keep its old value "1.jpeg".
The reason this might appear to work the other way around (when $compartment = 1) is because $currentfile is initialized with garbage on first use which is in if(file_exists($currentfile)). This of course evaluates to false so execution jumps to the else part.
HTH
place whole if/else block inside foreach and replace file_exists($currentfile) with file_exists($filename);
Seperate sections in a .php file are part of the same namespace / block / execution. If you use a variable in your first section, it will still be defined and and still have the same value in your second section.
There is no difference between
<?php
$MyValue = 'Value';
?>
<?php
echo $MyValue;
?>
and
<?php
$MyValue = 'Value';
echo $MyValue;
?>