printing 1 instead of filenames - php

I have some image collection in my specied directory.And i want to get their name using readdir() function.But instead of showing their names,it prints out a series of 1.How this can be done correctly ??I also want to know the reason for this behaviour
$dir='c:/xampp/htdocs/practice/haha/';
echo getcwd().'</br>';
if(is_dir($dir)){
echo dirname($dir);
$file=opendir($dir);
while($data=readdir($file)!==false){
echo $data.'</br>';
}
}

Operator precedence. This line:
while($data=readdir($file)!==false){
is being parsed/executed as
while ($data = (readdir($file) !== false))
^------------------------^
Note the extra brackets. $data is getting the boolean TRUE result of the !== comparison. You need to rewerite as
while(($data = readdir($file)) !== false){
^----------------------^
That'll make $data get the string returned from readdir, and then that string will be compared with boolean false.
Relevant docs: http://php.net/manual/en/language.operators.precedence.php

You probably can implement instead with scandir
function list_directory($directory) {
$result = new stdClass();
$result->path = $directory;
$result->children = array();
$dir = scandir($directory);
foreach($dir as $file) {
if($file == '.' || $file == '..') continue;
$result->children[] =
!is_dir($directory.$file) ? $file :
list_directory($directory.$file.'/');
}
return $result;
}
$dir='c:/xampp/htdocs/practice/haha/';
$result = list_directory($dir);
echo '<code><pre>';
var_dump($result);
echo '</pre></code>';
You can add in the function a filter for filetypes, or limit depth of recursion, things like that.

$data=readdir($file)!==false
You're setting the boolean result to $data. Surely you meant to do:
($data=readdir($file))!==false

Related

List all elements in array containing certain word in PHP

I'm attempting to make a search feature for my website using PHP. Right now, I have this code to create an array of all files in a directory, which works just fine, but I've hit a snag with my next step. I want it to now list all elements in that array that contain a certain word (the users search), this way I can do something with them later in HTML. My idea was to make a loop that runs strpos for each element and list only the ones it finds matches for. I've tried that, but it always gave me nothing. This is my honest attempt:
<?php
$search = "Pitfall";
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator('.')) as $filename)
{
if ($filename->isDir()) continue;
foreach ($filename as &$result)
{
$pos = strpos($result, $search);
if ($pos === true) {
echo "$result\n";
}
}
}
?>
Thank you for any help
I think your issue is with your conditional:
if ($pos === true)
strpos() does not return true. It returns the position of the string or false. See docs. You could instead use:
if ($pos !== false)
Edited:
The RecusiveIteratorIterator does not return a string. It returns an object. Here I am typecasting the object so that it gets the correct filename. From there, you don't need to iterate over again, as this is just a string at this point.
$search = "wp-config";
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator('.')) as $filename)
{
$filename = (string) $filename;
if (is_dir($filename)) continue;
$pos = strpos($filename, $search);
if ($pos !== false) {
echo "$filename <br />";
}
}

Illegal string offset 'result' in php echo

function RetrieveAllPages() {
$dir = '../pages';
$root = scandir($dir);
$result = array();
foreach($root as $value){
if($value === '.' || $value === '..') {
continue;
}
if(is_file("$dir/$value")) {
$result[]="$dir/$value";
continue;
}
foreach(find_all_files("$dir/$value") as $value){
$result[]=array('filename' => $value,);
}
}
print_r ($result);
var_dump($result);
return $result;
}
<?php
//echo'<select>';
foreach (RetrieveAllPages() as $value){
//echo "<option value='".$value['rolename']."'>".$value['rolename']."</option>";
echo'<input type="checkbox" value='.$value['result'].' name='.$value['result'].'/>';
}
//echo'</select>';
?>
getting this kind of error in php the code is above i have research and cant find any source that fits solution..any suggestion or idea is appreaciated
UPDATE
function RetrieveAllPages() {
$result = array();
$dir = "../pages";
$dh = opendir($dir);
while (false !== ($filename = readdir($dh))) {
$files[] = $filename;
}
print_r ($result);
var_dump($result);
return $result;
}
result is Array ( ) array(0) { }
if you don't want to list files recursively you can use this.
function RetrieveAllPages() {
$dir = '../pages';
$root = scandir($dir);
$result = array();
foreach($root as $value){
if($value === '.' || $value === '..') {
continue;
}
if(is_file("$dir/$value")) {
$result[]="$dir/$value";
}
//Note: removed the recursive call
}
print_r ($result);
var_dump($result);
return $result;
}
//echo'<select>';
foreach (RetrieveAllPages() as $value){
//echo "<option value='".$value['rolename']."'>".$value['rolename']."</option>";
// Note $value contains the filename!!!
echo'<input type="checkbox" value='.$value.' name='.$value.'/>' ;
}
//echo'</select>';
Here is another method which is much shorter! uses array_filter and anonymous function.
$all_files = array_filter(scandir('../pages'),function($v){return(!($v === '.' || $v === '..'));});
foreach ($all_files as $value){
echo'<input type="checkbox" value='.$value.' name='.$value.'/>' . $value .'<br/>';
}
You are getting an Illegal offset error because of the way you have defined the function RetrieveAllPages(). From the code, it basically scans a root folder for files and directories. If it encounters a directory, it tries to find all the files in that directory and pushes them into the result array which you return.
If you notice the output when you print the result array it would look something like this (just an example):
Array ( [0] => foo.jpg [1] => bar.txt [2] => Array ( [filename] => Testfile.pdf ) )
Now that you have an idea of what your function returns, let's get back to the echo statement:
foreach (RetrieveAllPages() as $value){
//Here the $value could be either string of the form root/foo etc or
echo $value; //String of file directly found in root directory
//It would be of the form of an array where you would get file names by doing something like:
echo $value[0]['filename']; //from the nested array
}
In any case, you are not using the string offset result anywhere in the array that you create in RetrieveAllPages(). The only string offset you use is filename. That is probably why you get this error when you try to create checkboxes out of these values. The way you handle this two kinds of values in your returned array is completely upto you.
Sidenote - The way you save your values, it's pretty likely that your function will return a nested array. One workaround could be if you, come across a directory instead of a file just prefix the string to the file names found in that directory instead of creating nested arrays with the prefix filename. It would greatly simplify your echo statements where you create the HTML checkboxes.
Like I said, the implementation is upto you and depends on what you are trying to achieve ultimately. Hope it gets you started in the right direction.

Find if a value exist in a CSV file with PHP

This is my code to check if a row of my .csv file contains a specific name, but it does not work.
I think it has something to do with the if statement.
$file_handle = fopen("sources.csv", "r");
while (!feof($file_handle) ) {
$line_of_text = fgetcsv($file_handle, 1024);
if ($line_of_text[0] = 'paul') {
echo 'Found';
}
}
fclose($file_handle);
I am trying to check in sources.csv files, for the name 'Paul' .
I can't use a database like MySQL for technical reasons.
Since you haven't provided a sample of your file, am submitting the following as an alternative.
Do note that in your present code, you are assigning using a single equal sign = instead of comparing using == or ===, just saying as an FYI.
if ($line_of_text[0] = 'paul') should read as if ($line_of_text[0] == 'paul')
Assuming the following .csv format (will work even without the commas) and is case-sensitive, consult Footnotes regarding case-insensitive search.
Paul, Larry, Robert
Code:
<?php
$search = "Paul";
$lines = file('sources.csv');
$line_number = false;
while (list($key, $line) = each($lines) and !$line_number) {
$line_number = (strpos($line, $search) !== FALSE);
}
if($line_number){
echo "Results found for " .$search;
}
else{
echo "No results found for $search";
}
Footnotes:
For a case-insensitive search, use stripos()
$line_number = (stripos($line, $search) !== FALSE);
Row number found on...
To give you the row's number where it was found:
$line_number = (strpos($line, $search) !== FALSE) ? $count : $line_number;
or (case-insensitive)
$line_number = (stripos($line, $search) !== FALSE) ? $count : $line_number;
then just echo $line_number;
Your problem is this line:
if ($line_of_text[0] = 'paul') {
This will always be true because you are assigning the value paul to $line_of_text[0] with the assign operator =. What you want to do is check if the two are equal, so you need to use the equality operator, ==. The line of code should be:
if ($line_of_text[0] == 'paul') {
There is also the === equality operator in PHP which checks for the same value AND same type. (This is a particularly nasty feature of PHP when compared to compiled languages)
e.g. consider: `$foo = 5; $bar = "5";
if ($foo === $bar) // this will be false because foo is an int, and bar is a string
if ($foo == $bar) // this will be true
Don't be confused with the != comparison operator:
if ($foo != $bar) // foo is not equal to bar (note the single =)
Try using in_array instead of ==
if(in_array('paul', $line_of_text)) {
// FOUND
}

PHP strpos not working

I've always had problems with strpos, I understand the num v. boolean issue, but I can NOT get this working. The $cur_key value is something like "page=>name"...
$pos = strpos($cur_key, "=>");
if ($pos !== false) {
$mod = explode("=>",$cur_key);
$path = $mod[0];
$param = $mod[1];
}else{
$path = $cur_key;
}
If it's in there it should split it into the two values but no matter what I try it's always just returning the original value...
$mod = explode('=>',$cur_key);
$path=$mod[0];
if (sizeof($mod)>1) $param=$mod[1]; else $param='';

How can I use PHP to check if a directory is empty?

I am using the following script to read a directory. If there is no file in the directory it should say empty. The problem is, it just keeps saying the directory is empty even though there ARE files inside and vice versa.
<?php
$pid = $_GET["prodref"];
$dir = '/assets/'.$pid.'/v';
$q = (count(glob("$dir/*")) === 0) ? 'Empty' : 'Not empty';
if ($q=="Empty")
echo "the folder is empty";
else
echo "the folder is NOT empty";
?>
It seems that you need scandir instead of glob, as glob can't see unix hidden files.
<?php
$pid = basename($_GET["prodref"]); //let's sanitize it a bit
$dir = "/assets/$pid/v";
if (is_dir_empty($dir)) {
echo "the folder is empty";
}else{
echo "the folder is NOT empty";
}
function is_dir_empty($dir) {
if (!is_readable($dir)) return null;
return (count(scandir($dir)) == 2);
}
?>
Note that this code is not the summit of efficiency, as it's unnecessary to read all the files only to tell if directory is empty. So, the better version would be
function dir_is_empty($dir) {
$handle = opendir($dir);
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
closedir($handle);
return false;
}
}
closedir($handle);
return true;
}
By the way, do not use words to substitute boolean values. The very purpose of the latter is to tell you if something empty or not. An
a === b
expression already returns Empty or Non Empty in terms of programming language, false or true respectively - so, you can use the very result in control structures like IF() without any intermediate values
I think using the FilesystemIterator should be the fastest and easiest way:
// PHP 5 >= 5.3.0
$iterator = new \FilesystemIterator($dir);
$isDirEmpty = !$iterator->valid();
Or using class member access on instantiation:
// PHP 5 >= 5.4.0
$isDirEmpty = !(new \FilesystemIterator($dir))->valid();
This works because a new FilesystemIterator will initially point to the first file in the folder - if there are no files in the folder, valid() will return false. (see documentation here.)
As pointed out by abdulmanov.ilmir, optionally check if the directory exists before using the FileSystemIterator because otherwise it'll throw an UnexpectedValueException.
I found a quick solution
<?php
$dir = 'directory'; // dir path assign here
echo (count(glob("$dir/*")) === 0) ? 'Empty' : 'Not empty';
?>
use
if ($q == "Empty")
instead of
if ($q="Empty")
For a object oriented approach using the RecursiveDirectoryIterator from the Standard PHP Library (SPL).
<?php
namespace My\Folder;
use RecursiveDirectoryIterator;
class FileHelper
{
/**
* #param string $dir
* #return bool
*/
public static function isEmpty($dir)
{
$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
return iterator_count($di) === 0;
}
}
No need to make an instance of your FileHelper whenever you need it, you can access this static method wherever you need it like this:
FileHelper::isEmpty($dir);
The FileHelper class can be extended with other useful methods for copying, deleting, renaming, etc.
There is no need to check the validity of the directory inside the method because if it is invalid the constructor of the RecursiveDirectoryIterator will throw an UnexpectedValueException which that covers that part sufficiently.
This is a very old thread, but I thought I'd give my ten cents. The other solutions didn't work for me.
Here is my solution:
function is_dir_empty($dir) {
foreach (new DirectoryIterator($dir) as $fileInfo) {
if($fileInfo->isDot()) continue;
return false;
}
return true;
}
Short and sweet. Works like a charm.
I used:
if(is_readable($dir)&&count(scandir($dir))==2) ... //then the dir is empty
Try this:
<?php
$dirPath = "Add your path here";
$destdir = $dirPath;
$handle = opendir($destdir);
$c = 0;
while ($file = readdir($handle)&& $c<3) {
$c++;
}
if ($c>2) {
print "Not empty";
} else {
print "Empty";
}
?>
Probably because of assignment operator in if statement.
Change:
if ($q="Empty")
To:
if ($q=="Empty")
# Your Common Sense
I think your performant example could be more performant using strict comparison:
function is_dir_empty($dir) {
if (!is_readable($dir)) return null;
$handle = opendir($dir);
while (false !== ($entry = readdir($handle))) {
if ($entry !== '.' && $entry !== '..') { // <-- better use strict comparison here
closedir($handle); // <-- always clean up! Close the directory stream
return false;
}
}
closedir($handle); // <-- always clean up! Close the directory stream
return true;
}
Function count usage maybe slow on big array. isset is ever faster
This will work properly on PHP >= 5.4.0 (see Changelog here)
function dir_is_empty($path){ //$path is realpath or relative path
$d = scandir($path, SCANDIR_SORT_NONE ); // get dir, without sorting improve performace (see Comment below).
if ($d){
// avoid "count($d)", much faster on big array.
// Index 2 means that there is a third element after ".." and "."
return !isset($d[2]);
}
return false; // or throw an error
}
Otherwise, using #Your Common Sense solution it's better for avoid load file list on RAM
Thanks and vote up to #soger too, to improve this answer using SCANDIR_SORT_NONE option.
Just correct your code like this:
<?php
$pid = $_GET["prodref"];
$dir = '/assets/'.$pid.'/v';
$q = count(glob("$dir/*")) == 0;
if ($q) {
echo "the folder is empty";
} else {
echo "the folder is NOT empty";
}
?>
Even an empty directory contains 2 files . and .., one is a link to the current directory and the second to the parent. Thus, you can use code like this:
$files = scandir("path to directory/");
if(count($files) == 2) {
//do something if empty
}
I use this method in my Wordpress CSV 2 POST plugin.
public function does_folder_contain_file_type( $path, $extension ){
$all_files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path ) );
$html_files = new RegexIterator( $all_files, '/\.'.$extension.'/' );
foreach( $html_files as $file) {
return true;// a file with $extension was found
}
return false;// no files with our extension found
}
It works by specific extension but is easily changed to suit your needs by removing "new RegexIterator(" line. Count $all_files.
public function does_folder_contain_file_type( $path, $extension ){
$all_files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path ) );
return count( $all_files );
}
I had a similar problem recently, although, the highest up-voted answer did not really work for me, hence, I had to come up with a similar solution. and again this may also not be the most efficient way to go about the problem,
I created a function like so
function is_empty_dir($dir)
{
if (is_dir($dir))
{
$objects = scandir($dir);
foreach ($objects as $object)
{
if ($object != "." && $object != "..")
{
if (filetype($dir."/".$object) == "dir")
{
return false;
} else {
return false;
}
}
}
reset($objects);
return true;
}
and used it to check for empty dricetory like so
if(is_empty_dir($path)){
rmdir($path);
}
You can use this:
function isEmptyDir($dir)
{
return (($files = #scandir($dir)) && count($files) <= 2);
}
The first question is when is a directory empty? In a directory there are 2 files the '.' and '..'.
Next to that on a Mac there maybe the file '.DS_Store'. This file is created when some kind of content is added to the directory. If these 3 files are in the directory you may say the directory is empty.
So to test if a directory is empty (without testing if $dir is a directory):
function isDirEmpty( $dir ) {
$count = 0;
foreach (new DirectoryIterator( $dir ) as $fileInfo) {
if ( $fileInfo->isDot() || $fileInfo->getBasename() == '.DS_Store' ) {
continue;
}
$count++;
}
return ($count === 0);
}
#Your Common Sense,#Enyby
Some improvement of your code:
function dir_is_empty($dir) {
$handle = opendir($dir);
$result = true;
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
$result = false;
break 2;
}
}
closedir($handle);
return $result;
}
I use a variable for storing the result and set it to true.
If the directory is empty the only files that are returned are . and .. (on a linux server, you could extend the condition for mac if you need to) and therefore the condition is true.
Then the value of result is set to false and break 2 exit the if and the while loop so the next statement executed is closedir.
Therefore the while loop will only have 3 circles before it will end regardless if the directory is empty or not.
$is_folder_empty = function(string $folder) : bool {
if (!is_dir($folder))
return TRUE;
// This wont work on non linux OS.
return is_null(shell_exec("ls {$folder}"));
};
$is_folder_empty2 = function(string $folder) : bool {
if (!is_dir($folder))
return TRUE;
// Empty folders have two files in it. Single dot and
// double dot.
return count(scandir($folder)) === 2;
};
var_dump($is_folder_empty('/tmp/demo'));
var_dump($is_folder_empty2('/tmp/demo'));

Categories