I have a full path which I would like to remove certain levels of it. So for instance,
/home/john/smith/web/test/testing/nothing/
I would like to get rid of 4 levels, so I get
/test/testing/nothing/
What would be a good of doing this?
Thanks
A simple solution is to slice the path up into parts, and then manipulate the array before sticking it back together again:
join("/", array_slice(explode("/", $path), 5));
Of course, if you wanted to remove that specific path, you could also use a regular expression:
preg_replace('~^/home/john/smith/web/~', '', $path);
One word of advice though. If your application is juggling around with paths a lot, it may be a good idea to create a class to represent paths, so as to encapsulate the logic, rather than have a lot of string manipulations all over the place. This is especially a good idea, if you mix absolute and relative paths.
Why are you all using regular expressions for something that requires absolutely no matching; CPU cycles are valuable!
str_replace would be more efficient:
$s_path = '/home/john/smith/web/test/testing/nothing/';
$s_path = str_replace('john/smith/web/test/', '', $s_path);
And use realpath() to resolve any '../../' paths.
And remember dirname(__FILE__) gets the CWD and rtrim() is extremely useful for removing trailing slashes..
Related
Say I have a badly formatted path /public/var/www/html/images\uploads\
Are there any performance benefits between these two methods to "normalize" the slashes, or is it just a different way of doing things?
realpath($path) . DIRECTORY_SEPARATOR
str_replace('\\', '/', $path);
realpath() might and probably does take a tad more computation but it is doing more than str_replace() would. As to which you would use is up to you and depends on the application. realpath() will not only fix the format of strings.. but will also verify that a file exists by that name. Also, using realpath() will, in most cases, make your code more readable and easier to understand because it's naming better corresponds to it's functionality here (depending, again, on the application).
realpath()
I am looking to strip away a part of the following url yet have no experience with regex or if that's even what I would use.
I have this url:
/var/www/wordpress/wp-content/themes/Aisis-Framework/CoreTheme/AdminPanel/Template/Form/Update.php
I would like to strip away everything to form:
CoreTheme/AdminPanel/Template/Form/Update.php
Is there an easy way to do this, and one that is done such that the amount of content before "CoreTheme" could be x characters long, where x is any number.
It should also not match on the word CoreTheme as it might be any name, it should also not match on Aisis-Framework as that could also be any name...
how ever it is safe to assume that anything after CoreTheme is static. The above string will be turned into, using string replace:
CoreTheme_AdminPanel_Template_Form_Update.php
As I have done in this piece of code:
$class_name = str_replace('/', '_', $path . $name);
where path is, in my solution, CoreTheme/AdminPanel/Template/Form/Update.php and $name is Update
If "/var/www/wordpress/wp-content/themes/Aisis-Framework/" is constant I would just do:
str_replace("/var/www/wordpress/wp-content/themes/Aisis-Framework/","",$path);
Otherwise you would need something constant to get a pattern of, like the number of directories deep or a specific pattern to match.
I would like to (ideally) use GLOB_ONLYDIR and GLOB_BRACE at the same time, because I would like to do some pattern matching like I can do with files ala *.{txt,php,doc,...,<whatever>} but with directories.
However, all my attempts for now have been quite futile (even dared to try GLOB_BRACE | GLOB_ONLYDIR remembering my good ol' days of fopen and C with the O_ flags but, of course, no luck), including things like glob(glob($path, GLOB_BRACE), GLOB_ONLYDIR); and other similar failed attempts.
My intention is to count the number of directories from a given path, but I would like to (optionally) pass a matching pattern for counting specific ocurrences.
How can I do it with glob? (or... is there a better approach/alternative to what I'm trying to do?)
You can try grabbing all directories and intersecting them with all brace matches, e.g.
array_intersect(glob($plain_path, GLOB_ONLYDIR), glob($brace_path, GLOB_BRACE))
You'll just have to implement some way to discover what $plain_path is if you're only given the brace-match string (unless your situation is static enough for it to only ever be one path).
Whenever I work with PHP (often) I typically work on a Windows box, however I (try to) develop platform agnostic applications; one major point of issue being the use of directory separators.
As many know, doing any filesystem work in a Windows environment in PHP, you can use forward slashes in lieu of backwards, and PHP sorts it out under the hood. This is all fine when it comes to using string literals to pass a path to fopen() or whatever; but when retrieving paths, be it __FILE__ or expanding with realpath(), the paths retrieved are of course using the OS appropriate slashes. Also, I've noticed some inconsistencies in trailing slashes. Once or twice __DIR__ has appended one (a backslash) and realpath() too (I prefer the trailing slash, but not intermittently)
This is clearly a problem for string comparison, because instead of doing:
compare_somehow('path/to/file.php', __DIR__);
For the sake of reliability, I'm having to go:
compare_somehow('path/to/file.php', rtrim(strtr(__DIR__, '\\', '/'), '/') . '/');
This seems like alot of work. I can drop it into a function, sure; now I'm stuck with an arbitrary function dependency in all my OO code.
I understand that PHP isn't perfect, and accommodations need to be made, but surely there must exist some platform agnostic workaround to force filesystem hits to retrieve forward slashed paths, or at least a non-intrusive way to introduce a class-independent function for this purpose.
Summary question(s):
Is there some magical (though reliable) workaround, hack, or otherwise to force PHP to kick back forward slashed filesystem paths, regardless of the server OS?
I'm going to assume the answer is no to the above, so moving on; what provisions can I make to enforce forward slash (or whatever choice, really) as the directory separator? I'm assuming through the aforementioned filter function, but now where should it go?
Forward slash for everything. Even if the host OS separator is #*&#.
As I commented I can't really see why you would have to do this (I'd be interested in a quick description of the specific problem you are solving), but here is a possible solution using the output of __FILE__ as an example:-
$path = str_replace('\\', '/', __FILE__);
See it working
This will(should?) work regardless of the *slashes returned by the OS (I think).
Unfortunately I'm not aware of "some magical (though reliable) workaround, hack, or otherwise to force PHP to kick back forward slashed filesystem paths, regardless of the server OS" other than this. I imagine it could be wrapped in a helper class, but that still gives you an arbitary dependancy in your code.
Hey, so I am trying to learn some string functions in PHP and came across a senario I cannot figure out. I want to take a string like such: /var/www/html and remove everything after the last forward slash (including the forward slash) so I end up with /var/www
What would be the best way to go about this? Many thanks.
Try using dirname. It may handle special cases for you that you may not have anticipated if you went with a string manipulation route.
This should work:
$str = substr($str, 0, strrpos($str, '/') - 1);
...but see icktoofay's solution if you're only planning on using this to handle file paths.