using substring to add word to string - php

Not sure if the title for this is correct but here's my problem:
I have a table that hold image's url like so:
img/folder/imagename.jpg
Now I've created a thumbnail for each image in each folder, so if I want to display them I do a loop in my table and return all the url's but I need to add the word "thumbs" after "folder/" and before the "imagename.jpg"...Now because obviously the "folder" and "imagename" names differ in length then I can't do a count..the only thing I can figure is to look up that last "/" character and insert there and add on the "imagename.jpg" after it so end result would look like:
img/folder/thumbs/imagename.jpg

Just replace the path with a "deeper" path:
$path = str_replace('img/folder/', 'img/folder/thumbs/', $path);
There are lots of other ways to do this, but IMHO this one is perfectly clear on what it does. Theoretically it won't work universally (if your path contains multiple occurreces of img/folder/ for some reason), but let's just not go there.

you can also
$pathparts = explode("/",$path);
and then use $pathparts array to construct your path again. You would use it in cases you want to have more control over manipulating paths, but in heavy loads it's not very efficient.
echo $pathparts[0]."/".$pathparts[1]."/thumbs/".$pathparts[2];
//adition
And why not to update your database and script only save imagename.jpg
and then in the beginning of calling script define
define("IMGPATH", "img/folder/");
define("THUMBPATH", "img/folder/thumbs/");
and then call it
<?= IMGPATH."imagename.jpg" ?>
<?= THUMBPATH."imagename.jpg" ?>

Related

How to find and replace string In many files

What I need Is to go thru a directory that contains subdirectories. In each second level directory has a third level directory that contains a file with same file name for every second level directory.
In each of those files made in PHP there Is a variable that contains like: appversion = 'YYYYMMDD'. I need to modify this date for each appearance To eg appversion = '20190301'.
How to do this In Shell or with PHP?
Edit: sorry for the malformed question, this is what defines better what I need to do really
I am afraid the question was a little malformed.
What I need to do is:
1. To find in all subdirectories a file called "productver.php".
2. In each "productver.php" file find a variable called 'appversion'.
3. Replace the value with a given value that i provide.
Example: I provide a date that is "20190324" and I want to change this to the value of all 'appversion' variables. E.g. 'appversion = 20180121' ==> 'appversion = 20190324'. For this reason, I am afraid simple replace is not enough as I only need to replace the part which is on the right side of the "=" character. And I cannot seek for a specific date, because the dates of this variable change. All I know is that I need to replace those dates, on the right side of the "=" sign of variable 'appversion'.

Recursively mapping file paths in one folder to another folder

Let's say I have a folder (folder_1) with the following structure:
/folder_1
/dir_1
- file_1_1.txt
- file_1_2.txt
/dir_2
- file_2_1.txt
/dir_2_1
- file_2_1_1.txt
- file_1.txt
Now, let's say I have another folder (folder_2) with the following structure:
/folder_2
/dir_1
- file_1_1.txt
- default.txt
/dir_2
- file_2_1.txt
- default.txt
- default.txt
I need to map every file in folder_1 to a file in folder_2 such that:
/folder_1/dir_1/file_1_1.txt maps to /folder_2/dir_1/file_1_1.txt.
/folder_1/dir_1/file_1_1.txt maps to /folder_2/dir_1/default.txt
/folder_1/dir_2/file_2_1.txt maps to /folder_2/dir_2/file_2_1.txt
/folder_1/dir_2/dir_2_1/file_2_1_1.txt maps to /folder_2/dir_2/default.txt
/folder_1/file_1.txt maps to /folder_2/default.txt
I am not the best communicator, so hopefully, the above pattern makes sense to you guys. The question is language agnostic really, but an answer in PHP and/or Javascript would be really great.
So far, I was able to accomplish this in PHP using FileIterator, RecursiveDirectoryIterator, and a bunch of custom classes that extract and then map the path to the files one by one.
This makes me wonder if I am missing an easier way to do this simple mapping. Maybe using regex named groups or something?
**Edit: **
Is it possible that for each file (file path) in folder_1, we use a regex pattern to find (reduce) the best match out of a map of all file paths in folder_2?
Further edit:
This is for mapping data files in folder_1 to template files in folder_2. If for a file in folder_1, an exact matching file path (including filename) in folder_2 is not found, we look for default.txt. If default.txt is not found, then we move up a directory and use that parent directory's default.txt. This way, we keep moving up directory levels till we find the first default.txt.
First, use your recursive directory scanner to scan all of the folder_2 directory tree. Build a hash table that contains the file names, without the folder_2 prefix. So your hash table would contain:
/dir_1
/dir_1/file_1_1.txt
/dir_1/default.txt
/dir_2/file_2_1.txt
/dir_2/default.txt
/default.txt
Now, start scanning folder_1. When you get a file, strip folder_1 from the front, and look for the resulting string in the hash table. If it's there, then you have a match.
If the file is not there, replace the last segment with "default.txt", and try again. So, when you begin scanning folder_1, you get:
/folder_1/dir_1/file_1_1.txt
You look up dir_1/file_1_1.txt in the hash table and find it. You have a match.
Next, you get /folder_1/dir_1/file_1_2.txt. You look up /dir_1/file_1_2.txt in the hash table and don't find it. So you replace file_1_2.txt with default.txt, giving you /dir_1/default.txt. You look that up in the hash table, find it, and you have a match.
Now, if /dir_1/default.txt did not exist, then you would again adjust the file name to remove the last directory. That is, you'd remove /dir_1, and you'd look up /default.txt in the hash table.
In pseudo code it looks like this:
for each file in folder_1
name = strip `/folder_1` from the name
if name in hash table then
match found
continue (next file)
end if
replace file name (everything after the last '/') with "default.txt"
do
if name in hash table then
match found
continue (next file)
end if
remove the last slash, and everything between it and the previous slash.
(so "/dir_1/default.txt" becomes "/default.txt")
while name.length > 0
// if you get here, no match was found
end for

php text file news updates

I am trying to make a news feed type thing in php.
I have a text file - news.txt and a php file index.php.
I have done the surrounding code and opening/closing the text file. Now I am stuck how to insert the new news item $newsnew to the top of the news.txt file and how to delete the old bottom news file in the news.txt file.
Is there any way to do this without deleting the whole file and writing it all again?
EDIT: Each news item is just a small string, say 500 characters, a single line.
Use a database.
If you really must use text files, use a different file for every news-item and name them sequentially like:
news001.txt
news002.txt
etc.
Then you can just add and delete files, read the directory and display what´s there.
Use the file() function to import the items in news.txt as an array, and use array_unshift() to add the new first item, and array_pop() to remove the last item. Join the array back into a single string and write it to news.txt:
$items = file('news.txt');
array_unshift($items, 'New item 1');
array_pop($items);
$newstext = implode(PHP_EOL, $items);
// write $newstext to the external file
If this is a XML file you could read it, parse it and delete the last child in the DOM. But if you have all your data in a DB it could be much easier to rewrite the file every time.
EDIT: after your edit: yes, you can do it like this:
write your new line to a new file
read the old file line by line and write it to the new one
skip the last line (detected by counting or EOF)
delete the old file and rename the new
No, there is not. But you might consider storing the messages in revers order. That way you only need to append to news.txt when new news arrive.
You are not going to be able to prepend to the beginning of the file without writing the whole thing out again. You could append to the end of it with the "a" mode flag to fopen(), but still to delete the oldest item you'll need to write out the entire file again.
Really, a database is solution here instead of a single text file.
There are many ways you can do it using the flat text file, but I'm not really sure it it's worth it. You can use some lightweight structured file or embedded database. For example SQLite, which would store it in normal file, no additional setup needed.

Check URL for a folder

How can I check the URL path for certain folders? I ask so that if we're in a certain folder, we can make a tab selected in the nav bar (just apply a style to that specific li).
So far I know
$pagePath = $_SERVER['REQUEST_URI'];
So I can get a return that says something like /music/song/120/ (or whatever it is). What kind of php function can I use that says
if $pagePath has "music", then do this. Meaning, if the path is /music/ or /music/song, I should be able to
I plan on using this multiple times,
if $pagePath has downloads do this
if $pathPath has band do this
and so on.
Any suggestions?
You could explode() the path on / and then use in_array() to check for existence.
However, this could yield problems with paths like /bands/something/music where the state would depend on whether you check for bands before music or vice versa. In that case you could explode() with $limit = 2 (to get only two parts, i.e., split on first / only) and compare your predefined path segments to the first part of the exploded path.
E.g.
$path = trim('/bands/something/music', '/');
$parts = explode('/', $path, 2); // ['bands', 'something/music']
switch ($parts[0]) {
case 'music':
// ...
case 'bands':
// ...
}
Try strpos()
e.g.
if(strpos($_SERVER['REQUEST_URI'],'music')>0)
{
# URL contains music
}
A quick way: you could use strpos: http://www.php.net/manual/en/function.strpos.php

Preg_match help : selecting files in a folder

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_'));
}

Categories