I have a delete button on my page, that delete button has to delete a certain entry in my database (not too difficult), it has to delete the entire folder where the file that holds the delete button is in (also doable), but I also want it to delete another folder that's placed somewhere else and I'm not sure how to do that. Using
dirname(__FILE__);
I am able to get the filepath where the file holding the delete button is located. That results in this:
mywebsite.nl/subdomains/dongen/httpdocs/s-gravenmoer/aandrijvingenenbesturingen/logo4life
The filepath that I also want to delete is quite similair, but a little different. The last 3 folders a variable, so their lenght (in characters) is always different. However, the second to last folder has to be deleted from this filepath so this remains:
mywebsite.nl/subdomains/dongen/httpdocs/s-gravenmoer/logo4life
Is there a way to do this with PHP? Using substr or something like that perhaps?
Thanks!
I think this should do the trick:
$folderToRemove = preg_replace( '#^(.*)/(.*?)/(.*?)$#', "$1/$3", dirname(__FILE__) );
You can try using "glob." Details in www.php.net/glob
You can try:
$files = glob('subdomains/dongen/httpdocs/*/logo4life');
foreach ($files as $file) {
unlink($file); // note that this is very dangerous though, you may end up deleting a lot of files
}
You don't need anything fancy, as you guessed, a simple str_replace will do it:-
$file = 'mywebsite.nl/subdomains/dongen/httpdocs/s-gravenmoer/aandrijvingenenbesturingen/logo4life';
var_dump(str_replace('aandrijvingenenbesturingen/', '', $file));
Output:-
string 'mywebsite.nl/subdomains/dongen/httpdocs/s-gravenmoer/logo4life' (length=62)
$path = "mywebsite.nl/subdomains/dongen/httpdocs/s-gravenmoer/aandrijvingenenbesturingen/logo4life";
$regex = "/(.*\/).*\/(.*)/";
$matches = array();
preg_match($regex, $path, $matches);
// var_dump($matches);
$new_path = $matches[1].$matches[2];
echo $new_path;
Above code uses preg_match for matching a regexp in a string.
Related
I have a folder that stores some thousands of pictures files.
I want to change the name of each file that matches the condition.
The idea is if the file name has _10 change to _ten, if has _5 change to _five.
So, xxdf23_10hy.jpg should be xxdf23_tenhy.jpg, 16_5_gt5.jpg should change to 16_five_gt5.jpg. But if file mane is gdjd_7.jpg, do nothing.
The code is working good, but it is matching the string ".." that should not be matched.
This is the part of the code:
$photoPath="../pic/";
$dir = new DirectoryIterator($photoPath);
foreach ($dir as $fileinfo) {
$filename = $fileinfo->getFilename();
if(preg_match($filename, "/_10/")){
//change te name to "_ten"
}
elseif(preg_match($filename, "/_5/")){
//change te name to "_five"
}
}
Something is not good with the way I am using the preg_match function.
But if I try it inside regex tester it works good.
What am I missing?
You've got your subject and pattern switched in the preg_match() commands. Try this:
if (preg_match("/_10/", $filename)) {
// more code
}
http://php.net/manual/en/function.preg-match.php
No need for the overhead of regex here at all. Perhaps simple glob() and str_replace() would meet your needs.
$photoPath="../pic/";
$replacements = array(
'_5' => '_five',
'_10' => '_ten'
);
foreach ($replacements as $pattern => $replace) {
$files = glob($photoPath . '*' . $pattern . '*');
foreach($files as $file) {
$old_name = $file;
$new_name = str_replace($pattern, $replace, $old_name);
rename($old_name, $new_name);
}
}
Here we don't even use regex or PHP string searching functionality to find the files we want to change. We use glob() which is basically a direct call to underlying libc glob() function and should perform significantly better and with less memory usage than the DirectoryIterator with post-filter functionality you are currently using. DirectoryIterator is probably overkill here anyway unless you are doing more complex file operations. glob() would filter your file names for you, meaning you are not doing useless regex searches against every file contained in DirectoryIterator object like you are currently doing.
The actual filepath name change is executed using basic str_replace(). You don't currently show how you are doing this, but I would imagine you would implement something similar or possibly just use preg_replace() rather than preg_match() if you desire to stick with regex approach.
This is a tricky one...I am trying to replace some strings in a file that i hold in array.
Because there are a lot of files...i've been trying to find the fastest way possible.
I tried this (which worked) but it was slow.
First parsed all the files and got an array of the values i want to
change (lets say 500).
Then I wrote a foreach loop to parse through the files one by one.
Then inside that, another foreach loop to go through the values one by one
preg_replacing the file for any occurrences of the array value.
This takes forever though cause not all files need to be parsed with 500 array elements.
So i am changing the code now like this:
Parse every file and make an array of the values i want to replace.
Search the file again for all the occurrences for each array value and replace it.
Save the file
I think this will be much faster that the old way...The problem i am having though now is with the read/write loop, and the array loop...
I want to do this as fast as possible...cause there will be a lot of files to parse and some have 100+ values.
So far i got this in a function.
function openFileSearchAndReplace($file)
{
$holdcontents = file_get_contents($file);
$newarray = makeArrayOfValuesToReplace($holdcontents);
foreach ($newarray as $key => $value) {
$replaceWith = getNewValueFor($value);
$holdcontent = preg_replace('/\\b'.$value.'\\b/', $replaceWith, $holdcontents);
}
file_put_contents($file, $holdcontent, LOCK_EX); //Save and close
}
Now, this doesnt work...it just changes 1 value only because i have file_put_contents and file_get_contents outside of the foreach. (Not to mention that it replaces values that it shouldnt replace. Probably cause the read/write are outside of the loop.) I have to put them inside to work..but thats gonna be slow..cause it take 3-4seconds per file to do the change since there are a lot of elements in the array.
How can i "Open the file", "Read it", "Change ALL values first", "Then save close the file", so i can move to the next.
EDIT:
Maybe i am not explaining it well i dont know...or is this too complicated....I have to parse the array of values...there is no way i can avoid that...but instead of (In every loop), i open the file search and replace 1 value, close the file.....I want to do this:
Open the file, get the content in an array or string or whatever. For all the values i have keep replacing the text with the equivalent value, and when all the values are done...that array or string write to the file. So i am only opening/closing the file once. Instead of waiting for php to read/write/close all the time.
-Thanks
How about just using str_replace(mixed $search , mixed $replace , mixed $subject)?
You can have an array of search strings which will be replaced by their corresponding item in the replace array and as the PHP manual says:
If you don't need fancy replacing rules (like regular expressions), you should always use this function instead of preg_replace().
Also just close the file and reopen it with mode 'w'. File will be truncated to 0 length
Added Edit
$fileContents = file_get_contents("theFile");
$search = array('apples', 'oranges');
$replace = array('pears', 'lemons');
$newContents = str_replace($search, $replace, $fileContents);
$handle = fopen("theFile","w");
fwrite($handle, $newContents);
fclose($handle);
That's it your file has all the old strings replaced with new ones.
There is no solution to the problem. file_get_contents and file_put_contents simply doesnt work like that.
I appreciate everyone's attention to the problem.
I am stuggling to comprehend how to accomplish the following task "
From : http://www.example.com/main/this_dir/page.html
I would like an output of : This Dir
When using $_SERVER['REQUEST_URI'] i can get this output :
*/main/this_dir/*
I would like to now take that and strip the last string between the two /'s so i end up with
*this_dir*
I would then like to take that string and turn it into
This Dir
There is a slight complication with this too because the directory could simply be called /this/ and not /this_dir/, but it is always one or the other and the text does change whereas the words i used were merely an example.
If anyone has any suggestions, input or feedback as to how i could accomplish this task it would be greatly appreciated! I do have a vague idea of how i could strip the last directory name from the request_uri string but i would really like to know if it would even be possible to transform the string in the way that i have described, using PHP.
You can use the basename function to get the "this_dir" part, so then it's simply a case of doing something like this:
$directoryName = ucwords(str_replace('_', ' ', basename($_SERVER['REQUEST_URI'])));
Edit
Slightly more convoluted example that will work for pages such as "/main/this_dir/something.php":
$directoryName = ucwords(str_replace('_', ' ', basename(substr($_SERVER['REQUEST_URI'], 0, strrpos($_SERVER['REQUEST_URI'], '/')))));
This is just stripping anything after the final "/" before passing to basename to ensure it'll work as before. Note that this will NOT work though for URLs without a trailing "/" such as "/main/this_dir" - in this case it would output "Main".
$path = explode("/", dirname($_SERVER['REQUEST_URI']));
$directory = end($path);
This should give you the last directory in the path.
Then you can do:
$dirParts = explode("_", $directory);
$dirName = implode(" ", array_map("ucfirst", $dirParts));
To get the directory name in a user-friendly format.
Edit: In fact, as RobMaster said, it is probably easier to do ucwords(str_replace("_", " ", $directory))
basically if I have a string like this:
$str = \data1\data2\data3\data_tmp\file.pgp
can anyone tell me how to get the last part 'file.pgp'?
TIA.
You are looking for the basename() function.
This function takes a file path and returns the file name without the suffix (the final part of your file name that specifies its type)
$last = array_pop(explode('\\', $str));
You don't need foreach for that. It's used when you have to iterate through the whole collection (in your case, array).
If you need to get the remaining part of the string:
$segments = explode('\\', $str);
$last = array_pop($segments);
It will be in $segments, as an array. If you want to convert it back to a string, then use join('\\', $segments). However, if this is a Windows path and you're running PHP on Windows, then you should be using the basename and dirname functions.
perhaps pathinfo() will give you what you need
if that doesn't do it try
$path = str_replace('\\', '/', $path)
first
I have the following code that selects all the different template files out of a folder... The file names I have are:
template_default.php
template_default_load.php
template_sub.php
template_sub_load.php
I only want to select the ones without the _load in the file name so I used this code:
preg_match('/^template_(.*)[^[_load]]{0}\.php$/i', $layout_file, $layout_name)
The code works fine except it cuts the last character off the result... Instead of returning default or sub when I echo $layout_name[1], it shows defaul and su...
Any ideas what is wrong with my code?
This part is totally up the creek:
[^[_load]]{0}
This is the regex you want:
/^template_(.*)(?<!_load)\.php$/i
You'll have to use negative assertions. (read below why not)
preg_match('/^template_(.*?)(?!_load)\.php$/i', $layout_file, $layout_name)
Edit: come to think of it, that regexp won't actually work because "_load" will be consumed by the .*? part. My advice: don't use preg_match() to capture the name, use it to skip those that end with _load, e.g.
foreach (glob('template_*') as $filepath)
{
if (preg_match('#_load\\.php$', $filepath))
{
// The file ends with _load
}
$filename = basename($filepath);
$layout_name = substr($filename, strlen('template_'));
}