php glob() alternatives - php

I have a wordpress theme that uses glob() function. THe problem is my hosting company has disabled glob(). how to modify the code so that it works using other php functions (opendir() maybe ?)
here is the code:
function yiw_get_tabs_path_files() {
$theme_files_path = YIW_THEME_FUNC_DIR . 'theme-options/';
$core_files_path = YIW_FRAMEWORK_PATH . 'theme-options/options/';
$tabs = array();
foreach ( glob( $theme_files_path . '*.php' ) as $filename ) {
preg_match( '/(.*)-options\.(.*)/', basename( $filename ), $filename_parts );
$tab = $filename_parts[1];
$tabs[$tab] = $filename;
}
foreach ( glob( $core_files_path . '*.php' ) as $filename ) {
preg_match( '/(.*)-options\.(.*)/', basename( $filename ), $filename_parts );
$tab = $filename_parts[1];
$tabs[$tab] = $filename;
}
return $tabs;
}

You can use the combination of opendir, readdir and closedir as you
suggested.
// open the directory
if ($handle = opendir($file_path)) {
// iterate over the directory entries
while (false !== ($entry = readdir($handle))) {
// match on .php extension
if (preg_match('/\.php$/', $entry) {
...
}
}
// close the directory
closedir($handle);
}
If these too are disabled, you can try the object-oriented Directory class.

Related

Find childrens folder with find_files php function

Need the function to find the folders 173 and 508 within children off children path.
Was trying to use:
find_files( $pathfolder .'/*'. '/*' . '173/', '.jpg$', 'move_orders');
The main code:
$pathfolder = "/home/production/ready/ordrers/";
find_files( $pathfolder . '173/', '/.jpg$/', 'move_orders');
find_files( $pathfolder . '508/', '/.jpg$/', 'move_orders');
function find_files($path, $pattern, $callback) {
$path = rtrim(str_replace("\\", "/", $path), '/') . '/' ;
$matches = Array();
$entries = Array();
$dir = dir($path);
while (false !== ($entry = $dir->read())) {
$entries[] = $entry;
}
$dir->close();
It seems like you need to get all the pictures in exact subfolder. You can use glob():
function find_files($path, $folder, $extension) {
return glob("$path/$folder/*.$extension");
}
$pathfolder = "/home/production/ready/ordrers/";
find_files( $pathfolder, '173', 'jpg');
find_files( $pathfolder, '508', 'jpg');
You also have $calback, but I don't see any usage of it.

Get list of multi layered folder structure in php [duplicate]

I'd like my script to scandir recursively,
$files = scandir('/dir');
foreach($files as $file){
if(is_dir($file)){
echo '<li><label class="tree-toggler nav-header"><i class="fa fa-folder-o"></i>'.$file.'</label>';
$subfiles = scandir($rooturl.'/'.$file);
foreach($subfiles as $subfile){
// and so on and on and on
}
echo '<li>';
} else {
echo $file.'<br />';
}
}
I'd like to loop this in a way that for each dir found by scandir, it runs another scandir on the folders that have been found within that dir,
So dir 'A' contains dir 1/2/3, it should now scandir(1), scandir(2), scandir(3)
and so on for each dir found.
How can I manage to implement this easily without copy pasting the code over and over in every foreach?
EDIT: Since the answers are nearly the very same as I already tried, I'll update the question a bit.
With this script I need to create a treeview list. With the current posted scripts the following get's echo'd happens:
/images/dir1/file1.png
/images/dir1/file2.png
/images/dir1/file3.png
/images/anotherfile.php
/data/uploads/avatar.jpg
/data/config.php
index.php
What I actually need is:
<li><label>images</label>
<ul>
<li><label>dir1</label>
<ul>
<li>file1.png</li>
<li>file2.png</li>
<li>file3.png</li>
</ul>
</li>
<li>anotherfile.php</li>
</ul>
</li>
<li><label>data</label>
<ul>
<li><label>uploads</label>
<ul>
<li>avatar.jpg</li>
</ul>
</li>
<li>config.php</li>
</ul>
</li>
<li>index.php</li>
And so on, Thank you for the already posted answers!
I know this is an old question but I wrote a version of this that was more functional. It doesn't use global state and uses pure functions to figure things out:
function scanAllDir($dir) {
$result = [];
foreach(scandir($dir) as $filename) {
if ($filename[0] === '.') continue;
$filePath = $dir . '/' . $filename;
if (is_dir($filePath)) {
foreach (scanAllDir($filePath) as $childFilename) {
$result[] = $filename . '/' . $childFilename;
}
} else {
$result[] = $filename;
}
}
return $result;
}
You can scan directory recursively in this way the target is your top most directory:
function scanDir($target) {
if(is_dir($target)){
$files = glob( $target . '*', GLOB_MARK ); //GLOB_MARK adds a slash to directories returned
foreach( $files as $file )
{
scanDir( $file );
}
}
}
You can adapt this function for your need easily.
For example if would use this to delete the directory and its content you could do:
function delete_files($target) {
if(is_dir($target)){
$files = glob( $target . '*', GLOB_MARK ); //GLOB_MARK adds a slash to directories returned
foreach( $files as $file )
{
delete_files( $file );
}
rmdir( $target );
} elseif(is_file($target)) {
unlink( $target );
}
You can not do this in the way you are doing.
The following function gets recursively all the directories, sub directories so deep as you want and the content of them:
function assetsMap($source_dir, $directory_depth = 0, $hidden = FALSE)
{
if ($fp = #opendir($source_dir))
{
$filedata = array();
$new_depth = $directory_depth - 1;
$source_dir = rtrim($source_dir, '/').'/';
while (FALSE !== ($file = readdir($fp)))
{
// Remove '.', '..', and hidden files [optional]
if ( ! trim($file, '.') OR ($hidden == FALSE && $file[0] == '.'))
{
continue;
}
if (($directory_depth < 1 OR $new_depth > 0) && #is_dir($source_dir.$file))
{
$filedata[$file] = assetsMap($source_dir.$file.'/', $new_depth, $hidden);
}
else
{
$filedata[] = $file;
}
}
closedir($fp);
return $filedata;
}
echo 'can not open dir';
return FALSE;
}
Pass your path to the function:
$path = 'elements/images/';
$filedata = assetsMap($path, $directory_depth = 5, $hidden = FALSE);
$filedata is than an array with all founded directories and sub directories with their content. This function lets you scan the directories structure ($directory_depth) so deep as you want as well get rid of all the boring hidden files (e.g. '.','..')
All you have to do now is to use the returned array, which is the complete tree structure, to arrange the data in your view as you like.
What you are trying to do is in fact a kind of file manager and as you know there are a lot of those in the wild, open source and free.
I hope this will help you and I wish you a merry Christmas.
function getFiles(string $directory, array $allFiles = []): array
{
$files = array_diff(scandir($directory), ['.', '..']);
foreach ($files as $file) {
$fullPath = $directory. DIRECTORY_SEPARATOR .$file;
if( is_dir($fullPath) )
$allFiles += getFiles($fullPath, $allFiles);
else
$allFiles[] = $file;
}
return $allFiles;
}
I know this is old but i wanted to show a slightly different version of the other answers. Uses array_diff to discard the "." and ".." folders. Also the + operator to combine 2 arrays ( i rarely see this used so it might be useful for someone )
Though the question is old. But my answer could help people who visit this question.
This recursively scans the directory and child directories and stores the output in a global variable.
global $file_info; // All the file paths will be pushed here
$file_info = array();
/**
*
* #function recursive_scan
* #description Recursively scans a folder and its child folders
* #param $path :: Path of the folder/file
*
* */
function recursive_scan($path){
global $file_info;
$path = rtrim($path, '/');
if(!is_dir($path)) $file_info[] = $path;
else {
$files = scandir($path);
foreach($files as $file) if($file != '.' && $file != '..') recursive_scan($path . '/' . $file);
}
}
recursive_scan('/var/www/html/wp-4.7.2/wp-content/plugins/site-backup');
print_r($file_info);
Create a scan function and call it recursively...
e.g:
<?php
function scandir_rec($root)
{
echo $root . PHP_EOL;
// When it's a file or not a valid dir name
// Print it out and stop recusion
if (is_file($root) || !is_dir($root)) {
return;
}
// starts the scan
$dirs = scandir($root);
foreach ($dirs as $dir) {
if ($dir == '.' || $dir == '..') {
continue; // skip . and ..
}
$path = $root . '/' . $dir;
scandir_rec($path); // <--- CALL THE FUNCTION ITSELF TO DO THE SAME THING WITH SUB DIRS OR FILES.
}
}
// run it when needed
scandir_rec('./rootDir');
You can do a lot variation of this function. Printing a 'li' tag instead of PHP_EOL for instance, to create a tree view.
[EDIT]
<?php
function scandir_rec($root)
{
// if root is a file
if (is_file($root)) {
echo '<li>' . basename($root) . '</li>';
return;
}
if (!is_dir($root)) {
return;
}
$dirs = scandir($root);
foreach ($dirs as $dir) {
if ($dir == '.' || $dir == '..') {
continue;
}
$path = $root . '/' . $dir;
if (is_file($path)) {
// if file, create list item tag, and done.
echo '<li>' . $dir . '</li>';
} else if (is_dir($path)) {
// if dir, create list item with sub ul tag
echo '<li>';
echo '<label>' . $dir . '</label>';
echo '<ul>';
scandir_rec($path); // <--- then recursion
echo '</ul>';
echo '</li>';
}
}
}
// init call
$rootDir = 'rootDir';
echo '<ul>';
scandir_rec($rootDir);
echo '</ul>';
Modern way:
use RecursiveIteratorIterator;
use RecursiveDirectoryIterator;
$path = '/var/www/path/to/your/files/';
foreach ( new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path, RecursiveDirectoryIterator::SKIP_DOTS ) ) as $file ) {
// TODO: Uncomment to see additional information. Do your manipulations with the files here.
// var_dump( $file->getPathname() ); // Or simple way: echo $file;
// var_dump( $file->isFile() );
// var_dump( $file->isDir() );
// var_dump( $file->getFileInfo() );
// var_dump( $file->getExtension() );
// var_dump( $file->getDepth() );
}
function deepScan($dir = __DIR__){
static $allFiles = [];
$allFiles[$dir] = [];
$directories = array_values(array_diff(scandir($dir), ['.', '..']));
foreach($directories as $directory){
if(is_dir("$dir\\$directory")){
foreach(deepScan("$dir\\$directory") as $key => $value) $allFiles[$key] = $value;
}
else{
$allFiles[$dir][] = "$directory";
}
}
return $allFiles;
}

PHP scandir recursively

I'd like my script to scandir recursively,
$files = scandir('/dir');
foreach($files as $file){
if(is_dir($file)){
echo '<li><label class="tree-toggler nav-header"><i class="fa fa-folder-o"></i>'.$file.'</label>';
$subfiles = scandir($rooturl.'/'.$file);
foreach($subfiles as $subfile){
// and so on and on and on
}
echo '<li>';
} else {
echo $file.'<br />';
}
}
I'd like to loop this in a way that for each dir found by scandir, it runs another scandir on the folders that have been found within that dir,
So dir 'A' contains dir 1/2/3, it should now scandir(1), scandir(2), scandir(3)
and so on for each dir found.
How can I manage to implement this easily without copy pasting the code over and over in every foreach?
EDIT: Since the answers are nearly the very same as I already tried, I'll update the question a bit.
With this script I need to create a treeview list. With the current posted scripts the following get's echo'd happens:
/images/dir1/file1.png
/images/dir1/file2.png
/images/dir1/file3.png
/images/anotherfile.php
/data/uploads/avatar.jpg
/data/config.php
index.php
What I actually need is:
<li><label>images</label>
<ul>
<li><label>dir1</label>
<ul>
<li>file1.png</li>
<li>file2.png</li>
<li>file3.png</li>
</ul>
</li>
<li>anotherfile.php</li>
</ul>
</li>
<li><label>data</label>
<ul>
<li><label>uploads</label>
<ul>
<li>avatar.jpg</li>
</ul>
</li>
<li>config.php</li>
</ul>
</li>
<li>index.php</li>
And so on, Thank you for the already posted answers!
I know this is an old question but I wrote a version of this that was more functional. It doesn't use global state and uses pure functions to figure things out:
function scanAllDir($dir) {
$result = [];
foreach(scandir($dir) as $filename) {
if ($filename[0] === '.') continue;
$filePath = $dir . '/' . $filename;
if (is_dir($filePath)) {
foreach (scanAllDir($filePath) as $childFilename) {
$result[] = $filename . '/' . $childFilename;
}
} else {
$result[] = $filename;
}
}
return $result;
}
You can scan directory recursively in this way the target is your top most directory:
function scanDir($target) {
if(is_dir($target)){
$files = glob( $target . '*', GLOB_MARK ); //GLOB_MARK adds a slash to directories returned
foreach( $files as $file )
{
scanDir( $file );
}
}
}
You can adapt this function for your need easily.
For example if would use this to delete the directory and its content you could do:
function delete_files($target) {
if(is_dir($target)){
$files = glob( $target . '*', GLOB_MARK ); //GLOB_MARK adds a slash to directories returned
foreach( $files as $file )
{
delete_files( $file );
}
rmdir( $target );
} elseif(is_file($target)) {
unlink( $target );
}
You can not do this in the way you are doing.
The following function gets recursively all the directories, sub directories so deep as you want and the content of them:
function assetsMap($source_dir, $directory_depth = 0, $hidden = FALSE)
{
if ($fp = #opendir($source_dir))
{
$filedata = array();
$new_depth = $directory_depth - 1;
$source_dir = rtrim($source_dir, '/').'/';
while (FALSE !== ($file = readdir($fp)))
{
// Remove '.', '..', and hidden files [optional]
if ( ! trim($file, '.') OR ($hidden == FALSE && $file[0] == '.'))
{
continue;
}
if (($directory_depth < 1 OR $new_depth > 0) && #is_dir($source_dir.$file))
{
$filedata[$file] = assetsMap($source_dir.$file.'/', $new_depth, $hidden);
}
else
{
$filedata[] = $file;
}
}
closedir($fp);
return $filedata;
}
echo 'can not open dir';
return FALSE;
}
Pass your path to the function:
$path = 'elements/images/';
$filedata = assetsMap($path, $directory_depth = 5, $hidden = FALSE);
$filedata is than an array with all founded directories and sub directories with their content. This function lets you scan the directories structure ($directory_depth) so deep as you want as well get rid of all the boring hidden files (e.g. '.','..')
All you have to do now is to use the returned array, which is the complete tree structure, to arrange the data in your view as you like.
What you are trying to do is in fact a kind of file manager and as you know there are a lot of those in the wild, open source and free.
I hope this will help you and I wish you a merry Christmas.
function getFiles(string $directory, array $allFiles = []): array
{
$files = array_diff(scandir($directory), ['.', '..']);
foreach ($files as $file) {
$fullPath = $directory. DIRECTORY_SEPARATOR .$file;
if( is_dir($fullPath) )
$allFiles += getFiles($fullPath, $allFiles);
else
$allFiles[] = $file;
}
return $allFiles;
}
I know this is old but i wanted to show a slightly different version of the other answers. Uses array_diff to discard the "." and ".." folders. Also the + operator to combine 2 arrays ( i rarely see this used so it might be useful for someone )
Though the question is old. But my answer could help people who visit this question.
This recursively scans the directory and child directories and stores the output in a global variable.
global $file_info; // All the file paths will be pushed here
$file_info = array();
/**
*
* #function recursive_scan
* #description Recursively scans a folder and its child folders
* #param $path :: Path of the folder/file
*
* */
function recursive_scan($path){
global $file_info;
$path = rtrim($path, '/');
if(!is_dir($path)) $file_info[] = $path;
else {
$files = scandir($path);
foreach($files as $file) if($file != '.' && $file != '..') recursive_scan($path . '/' . $file);
}
}
recursive_scan('/var/www/html/wp-4.7.2/wp-content/plugins/site-backup');
print_r($file_info);
Create a scan function and call it recursively...
e.g:
<?php
function scandir_rec($root)
{
echo $root . PHP_EOL;
// When it's a file or not a valid dir name
// Print it out and stop recusion
if (is_file($root) || !is_dir($root)) {
return;
}
// starts the scan
$dirs = scandir($root);
foreach ($dirs as $dir) {
if ($dir == '.' || $dir == '..') {
continue; // skip . and ..
}
$path = $root . '/' . $dir;
scandir_rec($path); // <--- CALL THE FUNCTION ITSELF TO DO THE SAME THING WITH SUB DIRS OR FILES.
}
}
// run it when needed
scandir_rec('./rootDir');
You can do a lot variation of this function. Printing a 'li' tag instead of PHP_EOL for instance, to create a tree view.
[EDIT]
<?php
function scandir_rec($root)
{
// if root is a file
if (is_file($root)) {
echo '<li>' . basename($root) . '</li>';
return;
}
if (!is_dir($root)) {
return;
}
$dirs = scandir($root);
foreach ($dirs as $dir) {
if ($dir == '.' || $dir == '..') {
continue;
}
$path = $root . '/' . $dir;
if (is_file($path)) {
// if file, create list item tag, and done.
echo '<li>' . $dir . '</li>';
} else if (is_dir($path)) {
// if dir, create list item with sub ul tag
echo '<li>';
echo '<label>' . $dir . '</label>';
echo '<ul>';
scandir_rec($path); // <--- then recursion
echo '</ul>';
echo '</li>';
}
}
}
// init call
$rootDir = 'rootDir';
echo '<ul>';
scandir_rec($rootDir);
echo '</ul>';
Modern way:
use RecursiveIteratorIterator;
use RecursiveDirectoryIterator;
$path = '/var/www/path/to/your/files/';
foreach ( new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path, RecursiveDirectoryIterator::SKIP_DOTS ) ) as $file ) {
// TODO: Uncomment to see additional information. Do your manipulations with the files here.
// var_dump( $file->getPathname() ); // Or simple way: echo $file;
// var_dump( $file->isFile() );
// var_dump( $file->isDir() );
// var_dump( $file->getFileInfo() );
// var_dump( $file->getExtension() );
// var_dump( $file->getDepth() );
}
function deepScan($dir = __DIR__){
static $allFiles = [];
$allFiles[$dir] = [];
$directories = array_values(array_diff(scandir($dir), ['.', '..']));
foreach($directories as $directory){
if(is_dir("$dir\\$directory")){
foreach(deepScan("$dir\\$directory") as $key => $value) $allFiles[$key] = $value;
}
else{
$allFiles[$dir][] = "$directory";
}
}
return $allFiles;
}

replace some code with blank space in php

I want to change some code by replacing it with blank space in all php and other files in my project folder and sub folder files.
I have the following code.
if ($handle = # opendir("for testing")) {
while (($entry = readdir($handle)) ) {
if ($entry != "." && $entry != "..") {
$linecop = '/*god_mode_on*eval(test("ZXkViKSk7IA=="));*god_mode_off*/';
$homepage = file_get_contents($entry);
$string3=str_replace($linecop,'',$homepage);
$file = fopen($entry, "w") or exit("Unable to open file!");
fwrite($file, $string3);
fclose($file); //
}
}
closedir($handle);
}
But this code only works for one file. How do I change all files?
function recursive_replace( $directory, $search, $replace ) {
if ( ! is_dir( $directory ) ) return;
foreach ( glob( $directory . '/*' ) as $file ) {
if ( $file === '.' || $file === '..' ) continue;
if ( is_dir( $file ) ) recursive_replace( $file, $search, $replace );
$content = file_get_contents( $file );
$content = str_replace( $search, $replace, $content );
file_put_contents( $file, $content );
}
}
recursive_replace('/your/file/path', '/*god_mode_on*eval(test("ZXkViKSk7IA=="));*god_mode_off*/', '');
if you want to recursively search and replace, you should think of a recursive function :) Also, glob()/file_X_contents() are much nicer functions to use for file and directory needs. code not tested but is damn close to what you're looking for in any case.

Easiest way to extract images from a MS Word Document using PHP?

Is this possible to extract images from MS Word Documents using PHP? And if so, how?
Requirement: Definitely old-shool doc support, but preferably both old and new.
Create a new PHP file and name it as extract.php and add the following code in it.
<?php
/*Name of the document file*/
$document = 'attractive_prices.docx';
/*Function to extract images*/
function readZippedImages($filename) {
/*Create a new ZIP archive object*/
$zip = new ZipArchive;
/*Open the received archive file*/
if (true === $zip->open($filename)) {
for ($i=0; $i<$zip->numFiles;$i++) {
/*Loop via all the files to check for image files*/
$zip_element = $zip->statIndex($i);
/*Check for images*/
if(preg_match("([^\s]+(\.(?i)(jpg|jpeg|png|gif|bmp))$)",$zip_element['name'])) {
/*Display images if present by using display.php*/
echo "<image src='display.php?filename=".$filename."&index=".$i."' /><hr />";
}
}
}
}
readZippedImages($document);
?>
Now create another PHP file and name it as display.php and add the following code to it.
<?php
/*Tell the browser that we want to display an image*/
header('Content-Type: image/jpeg');
/*Create a new ZIP archive object*/
$zip = new ZipArchive;
/*Open the received archive file*/
if (true === $zip->open($_GET['filename'])) {
/*Get the content of the specified index of ZIP archive*/
echo $zip->getFromIndex($_GET['index']);
}
$zip->close();
?>
Source(s): Extracting Images from DocX using PHP
If you are extracting images from older files you have a couple of options.
Run a converter to update all files to DocX then use IntermediateHacker's code.
Find the VBA code necessary to extract the images, and then either create a macro and call this code via PHP's COM interface functions or call the code yourself via these functions.
The first thing to do though is find how to do it in VBA, that will make it much easier to do it in PHP.
Hope this help You and you can also format according to your need .
<?php
/**
* Created by PhpStorm.
* User: khalid
* Date: 04/26/2015
* Time: 10:32 AM
*/
class DocxImages {
private $file;
private $indexes = [ ];
/** Local directory name where images will be saved */
private $savepath = 'docimages';
public function __construct( $filePath ) {
$this->file = $filePath;
$this->extractImages();
}
function extractImages() {
$ZipArchive = new ZipArchive;
if ( true === $ZipArchive->open( $this->file ) ) {
for ( $i = 0; $i < $ZipArchive->numFiles; $i ++ ) {
$zip_element = $ZipArchive->statIndex( $i );
if ( preg_match( "([^\s]+(\.(?i)(jpg|jpeg|png|gif|bmp))$)", $zip_element['name'] ) ) {
$imagename = explode( '/', $zip_element['name'] );
$imagename = end( $imagename );
$this->indexes[ $imagename ] = $i;
}
}
}
}
function saveAllImages() {
if ( count( $this->indexes ) == 0 ) {
echo 'No images found';
}
foreach ( $this->indexes as $key => $index ) {
$zip = new ZipArchive;
if ( true === $zip->open( $this->file ) ) {
file_put_contents( dirname( __FILE__ ) . '/' . $this->savepath . '/' . $key, $zip->getFromIndex( $index ) );
}
$zip->close();
}
}
function displayImages() {
$this->saveAllImages();
if ( count( $this->indexes ) == 0 ) {
return 'No images found';
}
$images = '';
foreach ( $this->indexes as $key => $index ) {
$path = 'http://' . $_SERVER['HTTP_HOST'] . '/' . $this->savepath . '/' . $key;
$images .= '<img src="' . $path . '" alt="' . $key . '"/> <br>';
}
echo $images;
}
}
$DocxImages = new DocxImages( "doc.docx" );
/** It will save and display images*/
$DocxImages->displayImages();
/** It will only save images to local server */
#$DocxImages->saveAllImages();
?>
If you are using the newer docx format it can easily be achieved because they are no more than a zip file. See the following link:
http://www.botskool.com/geeks/how-extract-images-docx-files-using-php

Categories