I'm trying to find all the files that called "testunit.php".
In addition i want to cut the first 23 chars of the string.
I tried this but this is not working.I get all the files.
$it = new RecursiveDirectoryIterator($parent);
$display = Array ( 'testunit.php');
foreach (new RecursiveIteratorIterator($it) as $file=>$cur) {
{
if ( In_Array ( $cur, $display ) == true )
$file = substr($cur, 23)
fwrite($fh,"<file>$file</file>");
}
Thank you!
see if glob helps you
Try
class TestUnitIterator extends FilterIterator
{
public function accept()
{
return (FALSE !== strpos(
$this->getInnerIterator()->current(),
'testunit.php'
));
}
public function current()
{
return sprintf(
'<file>%s</file>',
substr($this->getInnerIterator()->current(), 23)
);
}
}
Usage (codepad (abridged example)):
$iterator = new TestUnitIterator(
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(
'/path/to/iterate/over',
FilesystemIterator::CURRENT_AS_PATHNAME
)
)
);
foreach ($iterator as $file) {
echo $file, PHP_EOL;
}
Disclaimer: I wasn't in the mood to mock the filesystem or setup the required test files, so the above might need a little tweaking to work with the filesystem. I only tested with an ArrayIterator but there shouldn't be much to do if the above produces errors.
Related
This question has already been asked here, but it doesn't get me anywhere. I would like to be able to exclude certain files with relative paths from being copied, but the whole thing no longer works with subdirectories, so far I have only shown what subdirectories cannot be excluded without copying:
class MyRecursiveFilterIterator extends RecursiveFilterIterator {
//exluded Files and dirs
public static $FILTERS = array(
'config' => '',
);
public function accept() {
return !in_array(
$this->current()->getFilename(),
self::$FILTERS,
true
);
}
}
$dirItr = new RecursiveDirectoryIterator('../dir1');
$filterItr = new MyRecursiveFilterIterator($dirItr);
$itr = new RecursiveIteratorIterator($filterItr, RecursiveIteratorIterator::SELF_FIRST);
foreach ($itr as $filePath => $fileInfo) {
echo $fileInfo->getFilename() . "<br>";
}
I am trying to develop my understanding of php and would really appreciate any help. I have used a while loop to compare some values posted in my form with what is stored in a csv file.
This code works well. However, is it possible to achieve the same result using a FOR EACH loop or even a Do Until?? Or both?? Many thanks for any support
$file_handle = fopen("games.csv", "r"); # identify which file is being used.
while(!feof($file_handle))
{
$gameinfo = fgetcsv($file_handle);
if ($gameinfo[0] == $_POST["gameID"])
{
$GameName = "$gameinfo[2]";
$GameCost = "$gameinfo[4]";
$GameFound = true;
}
}
fclose($file_handle);
while is the best suited statement for this task, because you want to check for EOF before doing any read.
You can transform it in a do-while (there is no do-until in PHP) as an exercise:
do
{
if (!feof($file_handle))
{
$gameinfo = fgetcsv($file_handle);
if ($gameinfo[0] == $_POST["gameID"])
{
...
}
}
}
while(!feof($file_handle));
or shorter
do
{
if (feof($file_handle))
break;
$gameinfo = fgetcsv($file_handle);
if ($gameinfo[0] == $_POST["gameID"])
{
...
}
}
while(true);
but that's just a bad way to write a while.
Regarding foreach, quoting the doc
The foreach construct provides an easy way to iterate over arrays. foreach works only on arrays and objects, and will issue an error when you try to use it on a variable with a different data type or an uninitialized variable.
You can customize iteration over objects, this let you (Warning, layman language) use foreach on "custom objects" so that you can, in a way, extend the functionality of foreach.
For example to iterate over CSV files you can use this class
<?php
class FileIterator implements Iterator
{
private $file_handle = null;
private $file_name;
private $line;
public function __construct($file_name)
{
$this->file_name = $file_name;
$this->rewind();
}
public function rewind()
{
if (!is_null($this->file_handle))
fclose($this->file_handle);
$this->line = 1;
$this->file_handle = fopen($this->file_name, "r");
}
public function current()
{
return fgetcsv($this->file_handle);
}
public function key()
{
return $this->line;
}
public function next()
{
return $this->line++;
}
public function valid()
{
$valid = !feof($this->file_handle);
if (!$valid)
fclose($this->file_handle);
return $valid;
}
}
?>
and use it this way
$it = new FileIterator("game.csv");
foreach ($it as $line => $gameObj)
{
echo "$line: " . print_r($gameObj, true) . "<br/>";
}
Which produce something like
1: Array ( [0] => 0 [1] => Far Cry 3 )
2: Array ( [0] => 1 [1] => Far Cry Primal )
3: Array ( [0] => 2 [1] => Alien Isolation )
for this file
0,Far Cry 3
1,Far Cry Primal
2,Alien Isolation
I've been searching the database of questions on the forum, but can not get a solution that is oriented to my question.
I come to you, because I doubt has arisen with an autoloader that I'm developing.
The point is this, when I try to instantiate a class defined by me the autoloader works fine, but when I try to instantiate a class of the PHP core throws me the following error.
For example, when I try to do this:
$conn = new PDO (...);
Then throws me the following error:
Fatal error: Class 'PDO' not found in ...
I've noticed that the autoloader is trying to load the class from which I have defined routes to my classes.
My question is, how I can do to load a class of the PHP core if I'm using a custom autoloader?
I hope you can guide me to solve this problem that I have been presented.
In advance thank you very much.
Excuse me for not placing the code of custom autoloader, I missed.
The code is the same used in symfony but modified and simplified.
class ClassLoader {
private $prefixes = array ();
private $fallbackDirs = array ();
private $useIncludePath = false;
public function getPrefixes () {
return $this->prefixes;
}
public function getFallbackDirs () {
return $this->fallbackDirs;
}
public function addPrefixes ( array $prefixes ) {
foreach ( $prefixes as $prefix => $path ) {
$this->addPrefix ( $prefix, $path );
}
}
public function addPrefix ( $prefix, $paths ) {
if ( !$prefix ) {
foreach ( ( array ) $paths as $path ) {
$this->fallbackDirs [] = $path;
}
return;
}
if ( isset ( $this->prefixes [ $prefix ] ) ) {
$this->prefixes [ $prefix ] = array_merge ( $this->prefixes [ $prefix ], ( array ) $paths );
} else {
$this->prefixes [ $prefix ] = ( array ) $paths;
}
}
public function setUseIncludePath ( $useIncludePath ) {
$this->useIncludePath = $useIncludePath;
}
public function getUseIncludePath () {
return $this->useIncludePath;
}
public function register ( $prepend = false ) {
spl_autoload_register ( array ( $this, 'loadClass' ) , true, $prepend );
}
public function unregister () {
spl_autoload_unregister ( array ( $this, 'loadClass' ) );
}
public function loadClass ( $class ) {
if ( $file = $this->findFile ( $class ) ) {
require $file;
return true;
}
}
public function findFile ( $class ) {
if ( '\\' == $class [ 0 ] ) {
$class = substr ( $class, 1 );
}
if ( false !== $pos = strrpos ( $class, '\\' ) ) {
// namespaced class name
$classPath = str_replace ( '\\', DIRECTORY_SEPARATOR, substr ( $class, 0, $pos ) ) . DIRECTORY_SEPARATOR;
$className = substr ( $class, $pos + 1 );
} else {
// PEAR-like class name
$classPath = null;
$className = $class;
}
$classPath .= str_replace ( '_', DIRECTORY_SEPARATOR, $className ) . '.php';
foreach ( $this->prefixes as $prefix => $dirs ) {
if ( 0 === strpos ( $class, $prefix ) ) {
foreach ( $dirs as $dir ) {
if ( file_exists ( $dir . DIRECTORY_SEPARATOR . $classPath ) ) {
return $dir . DIRECTORY_SEPARATOR . $classPath;
}
}
}
}
foreach ( $this->fallbackDirs as $dir ) {
if ( file_exists ( $dir . DIRECTORY_SEPARATOR . $classPath ) ) {
return $dir . DIRECTORY_SEPARATOR . $classPath;
}
}
if ( $this->useIncludePath && $file = stream_resolve_include_path ( $classPath ) ) {
return $file;
}
}
}
But if you want to see the original file is here
https://github.com/symfony/symfony/blob/master/src/Symfony/Component/ClassLoader/ClassLoader.php
Well my friends.
I got the reason why I did not load the PDO class of the PHP core.
According to my research, I do one of two things:
Or put a backslash at the time of the class instances
$conn = new \PDO (...);
Or put the PDO class in the use clause.
use api\ecobd\nucleo\Conexion, PDO;
I commented that I chose the second because the first did not work.
Thanks anyway for the help given, served me well to better target my search to solve my problem :)
Check if PDO extension is loaded and PDO works without registering your auto loader. Auto loader should not effect core classes and you don't need an auto loader to load core classes.
How can I list all jpg files in a given directory and its subdirectories in PHP5 ?
I thought I could write a glob pattern for that but I can't figure it out.
thanx, b.
You can use a RecursiveDirectoryIterator with a filter:
class ImagesFilter extends FilterIterator
{
public function accept()
{
$file = $this->getInnerIterator()->current();
return preg_match('/\.jpe?g$/i', $file->getFilename());
}
}
$it = new RecursiveDirectoryIterator('/var/images');
$it = new ImagesFilter($it);
foreach ($it as $file)
{
// Use $file here...
}
$file is an SplFileInfo object.
without doing it for you. recursion is the answer here. a function that looks in a dir and gets a list of all files. filters out only th jpg's then calls its self if i finds any sub dirs
Wish I had time to do more & test, but this could be used as a starting point: it should (untested) return an array containing all the jpg/jpeg files in the specified directory.
function load_jpgs($dir){
$return = array();
if(is_dir($dir)){
if($handle = opendir($dir)){
while(readdir($handle)){
echo $file.'<hr>';
if(preg_match('/\.jpg$/',$file) || preg_match('/\.jpeg$/',$file)){
$return[] = $file;
}
}
closedir($handle);
return $return;
}
}
return false;
}
Is there a better/simpler way to find the number of images in a directory and output them to a variable?
function dirCount($dir) {
$x = 0;
while (($file = readdir($dir)) !== false) {
if (isImage($file)) {$x = $x + 1}
}
return $x;
}
This seems like such a long way of doing this, is there no simpler way?
Note: The isImage() function returns true if the file is an image.
Check out the Standard PHP Library (aka SPL) for DirectoryIterator:
$dir = new DirectoryIterator('/path/to/dir');
foreach($dir as $file ){
$x += (isImage($file)) ? 1 : 0;
}
(FYI there is an undocumented function called iterator_count() but probably best not to rely on it for now I would imagine. And you'd need to filter out unseen stuff like . and .. anyway.)
This will give you the count of what is in your dir. I'll leave the part about counting only images to you as I am about to fallll aaasssllleeelppppppzzzzzzzzzzzzz.
iterator_count(new DirectoryIterator('path/to/dir/'));
i do it like this:
$files = scandir($dir);
$x = count($files);
echo $x;
but it also counts the . and ..
The aforementioned code
$count = count(glob("*.{jpg,png,gif,bmp}"));
is your best best, but the {jpg,png,gif} bit will only work if you append the GLOB_BRACE flag on the end:
$count = count(glob("*.{jpg,png,gif,bmp}", GLOB_BRACE));
you could use glob...
$count = 0;
foreach (glob("*.*") as $file) {
if (isImage($file)) ++$count;
}
or, I'm not sure how well this would suit your needs, but you could do this:
$count = count(glob("*.{jpg,png,gif,bmp}"));
You could also make use of the SPL to filter the contents of a DirectoryIterator using your isImage function by extending the abstract FilterIterator class.
class ImageIterator extends FilterIterator {
public function __construct($path)
{
parent::__construct(new DirectoryIterator($path));
}
public function accept()
{
return isImage($this->getInnerIterator());
}
}
You could then use iterator_count (or implement the Countable interface and use the native count function) to determine the number of images. For example:
$images = new ImageIterator('/path/to/images');
printf('Found %d images!', iterator_count($images));
Using this approach, depending on how you need to use this code, it might make more sense to move the isImage function into the ImageIterator class to have everything neatly wrapped up in one place.
I use the following to get the count for all types of files in one directory in Laravel
$dir = public_path('img/');
$files = glob($dir . '*.*');
if ( $files !== false )
{
$total_count = count( $files );
return $totalCount;
}
else
{
return 0;
}
Your answer seems about as simple as you can get it. I can't think of a shorter way to it in either PHP or Perl.
You might be able to a system / exec command involving ls, wc, and grep if you are using Linux depending how complex isImage() is.
Regardless, I think what you have is quite sufficient. You only have to write the function once.
I use this to return a count of ALL files in a directory except . and ..
return count(glob("/path/to/file/[!\.]*"));
Here is a good list of glob filters for file matching purposes.
$nfiles = glob("/path/to/file/[!\\.]*");
if ($nfiles !== FALSE){
return count($nfiles);
} else {
return 0;
}