So far I have only worked with *, but, are there something like lookaheads, groups?
I would like to get all *.php except controller.php.
What I have to alter in this glob(dirname(__FILE__) . DIRECTORY_SEPARATOR . '*.php') call, to exclude controller.php?
Or should I avoid glob and work with something else instead?
php glob() uses the rules used by the libc glob() function, which is similar to the rules used by common shells. So the patterns that you are allowed to use are rather limited.
glob() returns an array of all the paths that match the given pattern. Filtering controller.php out the result array is one solution.
As per http://www.manpagez.com/man/3/glob/: (the backend behind php's glob()) The glob() function is a pathname generator that implements the rules for file name pattern matching used by the shell.
It is a single filter, no exceptions. If you want *.php, you'll get *.php.
Try this,
<?php
$availableFiles = glob("*.txt");
foreach ($availableFiles as $key => $filename) {
if($filename == "controller.php"){
unset($availableFiles[$key]);
}
}
echo "<pre>"; print_r($availableFiles);
?>
Related
What is the php's glob function starting point for pattern searching when given arguments like below.
$dirs = glob('*');
Does it resolve its path like many file handling functions.
The manual http://php.net/manual/en/function.glob.php states:
The glob() function searches for all the pathnames matching pattern according to the rules used by the libc glob() function, which is similar to the rules used by common shells.
and pulled from https://www.gnu.org/software/libc/manual/html_node/Calling-Glob.html and using "libc glob() function" as a starting reference, states:
The function glob does globbing using the pattern pattern in the current directory. It puts the result in a newly allocated vector, and stores the size and address of this vector into *vector-ptr. The argument flags is a combination of bit flags; see Flags for Globbing, for details of the flags.
Side note: The folks at PHP.net may have felt they didn't see the need to repeat those rules. Why? I don't know that and would be out of the scope of the question. It would however, have been nice for them to include a hyperlink as a reference (starting) point.
That will be the folder where your script is located.
The function glob does globbing using the requested pattern in the current directory.
Why use basename() in PHP scripts if what this function is actually doing may be written in 2 lines:
$subFolders = preg_split("!\\\|\\/!ui", $path); // explode on `\` or `/`
$name = array_pop($subFolder); // extract last element's value (filename)
Am I missing something?
However I guess this code above may not work correctly if file name has some \ or / in it. But that's not possible, right?
PHP may run on many different systems with many different filesystems and naming conventions. Using a function like basename() guarantees (or at least, is supposed to guarantee) a correct result regardless of the platform. This increases the code's portability.
Also, compare a simple basename() call to your code - which is more readable, and more obvious to other programmers in regards to what it is supposed to do?
glob("aaafolder/*php")
glob("bbbfolder/*php")
glob("cccfolder/*php")
Is it possible to simplify this?
glob("(?=aaafolder/*php)(?=bbbfolder/*php)(?=cccfolder/*php)")
The above returns nothing.
This note on the manual page of glob() seems to answer your question, saying that glob is not limited to a single directory : using GLOB_BRACE, you can specify several directories.
I'm quoting the example that #Ultimater gives there :
$results=glob("{includes/*.php,core/*.php}",GLOB_BRACE);
User-notes on the manual pages often contain useful informations and examples ;-)
As the PHP manual said, its the GLOB_BRACE flag.
glob("{aaafolder/*php,bbbfolder/*php,cccfolder/*php}", GLOB_BRACE)
I'm working on converting an old define()-based language/translation system to a more flexible one (probably JSON-based, but it's still open).
As part of this conversion, I will need to convert from 42 .php files with several thousand strings each to whatever format I'll be using. Some of the defined strings reference other defines or use PHP code. I don't need to keep this dynamic behaviour (it's never really dynamic anyway), but I will need to have the "current" values at time of conversion.
One define might look like this:
define('LNG_Some_string', 'Page $s of $s of our fine '.LNG_Product_name);
Since all defines have an easily recognizable 'LNG_' prefix, converting a single file is trivial. But I'd like to make a small script which handles all 42 in one run.
Ideally I'd be able to either undefine or redefine the define()'s, but I can't find a simple way of doing that. Is this at all possible?
Alternatively, what would be a good way of handling this conversion? The script will be one-off, so it doesn't need to be maintainable or fast. I just want it fully automated to avoid human error.
if speed is not important, so you can use get_defined_constants function.
$constans = get_defined_constants(true);
$myconst = array();
$myconst = $constans['user'];
$myconst will contain all constants defined by your script:-)
P.S: I'm not a good php coder, it was just a suggestion :-)
You can't undefine constants, but you can generate your new scripts by utiliising them and the constant() function:
<?php
/* presuming all the .php files are in the same directoy */
foreach (glob('/path/*.php') as $file) {
$contents = file_get_contents($file);
$matches = array();
if (!preg_match('/define\(\'LNG_(\w+)\'/', $contents, $matches) {
echo 'No defines found.';
exit;
}
$newContents = '';
include_once $file;
foreach ($matches as $match) {
$newContents .= "SOME OUTPUT USING $match AS NAME AND " . constant($match) . " TO GET VALUE";
}
file_put_contents('new_'.$file, $newContents);
}
?>
Defined constants can't be undefined. They're immutable.
Perhaps what you can do is get in right before they're defined and modify them in certain circumstances.
Is there a way to perform double require_once statement where the second one as a fallback if the first one fails?
For example: I can do this
mysql_query() or die("Boo");
Could I do:
require_once('filename') or require_once('../filename');
If one fails it reverts to the other?
You can't do this because of a weird little quirk in PHP. require_once() is a language construct, not a function. It will interpret the whole line as the argument:
(('filename') or require_once('../filename'))
(added braces for clarity) the result of this operation is 1.
Use is_readable() instead.
if (is_readable($filename))
require_once($filename);
else require_once("../$filename");
or a shorter version that should work:
require_once(is_readable($filename) ? $filename : "../$filename");
#Pekka is correct. I'd add something else though, that might get rid of the issue entirely. If you have files in several different places, you can edit the include paths so that require() and include() look in a variety of places. See set_include_path()
The example in the manual adds a new path to the existing include path:
$path = '/usr/lib/pear';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);