Creating a file/folder structure and zipping it up? - php

I have a directory of image files and I need a php script or shell script that will rename them, create a structure of nested directories, and then insert each image into a specified place in the directory hierarchy. Ideally I would just specify a parent directory for each file and a parent directory for each directory and it would build it. And then finally, I need the script to zip up the whole thing.
There's probably not an existing php class that will do all this for me, but if anyone knows of a php class or other script available online that would handle a lot of this logic that would be great.

I know its not PHP, but you might want to investigate something like this:
a shell script for renaming files (your dialect may vary, but the man pages are very helpful).
foreach img (/path/to/directory/*.jpg)
set newimg= `echo $img | sed 's,path/to/directory/(.+)\.jpg,new/path/$1newname.jpg/,'`
cp img newimg
end
If all the files in a particular directory are going to one location, something like the above might work. Essentially it loops through the target directory getting the names of the files that have a .jpg (or whatever) extension. Then it takes those names, including their path and subs in the new directory path and some change to the original file change. I've used , for the separator in the substitution because escaping all those path separators is a pain. Lastly, it copies the old file to the new location.
Since your directory needs are probably more complex than a hardcoded path allows for, you can include a line to parse your filepath/filename and determine what its target path should be; and use that in the substitution.
A snippet for creating a directory tree in one go can be found here.
You may also decide that find is a better fit for this than foreach because it can descend a directory structure as far as you like.

Related

Creating directories with regex same in url structure

I will mass download thousands of images from a server.
My problem is : filenames are same and they are located in different directories.
Ex:
http://domain.com/images/upload/2014/09/SKU00123/1.jpg
http://domain.com/images/upload/2014/09/SKU1501/1.jpg
I want to download them with the same directory structure.
c:\images\upload\2014\09\SKU00123\1.jpg
I can take the file name with basename command but i couldn't find a way to get the directory structure. I need php to create directories and save the files to that destination.
Is there a way to change the url structure to directory structure? Maybe with regex?
For the next time, please show us some PHP code. Have you already tried something?!
...You can easily do this in 2 steps:
Use parse_url to find the path(/images/upload/2014/etc..) of the URL.
Use mkdir with the recursive parameter to create these directories on your own system.

PHP recursively delete empty parent directories

Problem Background
I have a multimedia web applications where users can save and delete files. The saved files are used for various application wide functionalities.
When files are saved, they are put deep inside directory tree (usually 6 to 9 folders deep).
The files are put at such deep level to make sure that they are easily distinguishable by admin/superuser looking at file structure and to match with existing manual system.
For Example,
"UploadedAssets" is the root directory and can contain following folder structure : \ith\sp\cookery\ckpe\interactives\timestep\blahblah\item1\image01.png
\ith\sp\cookery\ckpe\interactives\timestep\blah_only\item1\image02.png
\ith\sp\cookery\ckpe\interactives\timestep\blah_only\item2\image03.png
\ith\sp\cookery\abcd\interactives\timestep\blahblah\item1\image66.png
The first 5 names are user selectable (from dynamic dropdown menus) form approx 20-25 options each.
The last 3 depends on whatever user inputs (e.g. category , title, etc.). This is received from user using text input fields. These can be 1 or up to 4 directories.
The last directory "item1" can have one or more files but no sub directories
Each directory EXCEPT the last one (item1) can have other sub directories
When I remove/delete a file, obviously program knows the full path of the file location.
Because of number of possible directory name options, even in the testing phase, the root "UploadedAssets" directory has exploded and there are plenty of empty unused directories and dead branches.
My question is
Once the user deletes one/more files from a directory (e.g. image01.png from item1),
How can I traverse up the tree from deleted file (going only to straight parents) and delete the parent node if its empty.
While deleting if one of the directoy has other children/files then not to delete that directory and finish the process.
While deleting stop at pre-defined root directory OR
Stop after going UP n directory levels
E.g. in the above given example directory structure,
if user deletes image01.png then it should delete item1 and blahblah directories
if user deletes image02.png then it should delete only its parent item1 directory
if user deletes image66.png then it should delete all parent directories including abcd
My Attempts / research
I know how to remove single directory using php's rmdir. But couldn't think on how can I use it recursively to solve my problem.
I have tried to get my head around following stuff, but I don't know if any of those can fit my problem
PHP: Unlink All Files Within A Directory, and then Deleting That Directory
Delete files then directory
http://php.net/manual/en/function.glob.php
https://stackoverflow.com/a/4490706/2337895
Because this has some overhead, I'm going to suggest that you only do this from PHP if absolutely needed. You can use the Linux find command for this:
find /path/to/dir -empty -type d -delete
I would put that in a cron job. If you like you can use the php system command to do this though:
system('find /path/to/dir -empty -type d -delete', $retval);
Using this you would simply delete the file and then let this run only every day or so to go through and take care of any empty directories. This may seem more hackish than making it all in PHP but it'll run much faster. It is less portable but that shouldn't matter too much for most sites. Save this as rdel.bat (I walways make sure you have the [Show hidden file extensions][2] explorer folder option turned on but if you don't then use the drop-down in your text editors Save As... dialog to ensure it has the proper extension).
UPDATE:
To do the same thing in Windows use a batch file with just this one line:
for /f "delims=" %%d in ('dir /s /b /ad ^| sort /r') do rd "%%d"
Test this by changing to a directory and running your new file. It should remove any empty directories below the current.
To schedule this just add an entry to your task scheduler. That is a little different depending on which version of Windows you use. Be sure to set the working directory correctly (this is how the batch file knows where to start).
The problem with this is that in Windows a lot of junk files get created in empty directories (ie Thumbs.db). You can handle that by adding code to your batch file to remove any of those files too:
del /s /q Thumbs.db
Add this above the other line and repeat for anything else which may be unneeded.

How to correctly link files?

From my previous experience, I've almost always had problems with linking files with my website projects.
For example, linking CSS styles, Javascript files and including files in PHP. The problem is, that on my PC, the directory of my project was /www/project-name/ and when I put the project on a server, the directory would be just /www/. When I uploaded the project to a server, images wouldn't show, styles wouldn't work, database connections wasn't set, functions were not defined etc...
So my question is: What is the best and most efficient way to link/include files?
Something that will work no matter what the directory of the project is, and possibly, if I include project/includes/mysql.class.php in file1.php, and I move that file to a different directory, it would still properly include project/includes/mysql.class.php
You should use relative paths.
Instead of specifying the full path ('/www/project-name/includes/whatever.php'), use a path relative to the current location:
'./includes/whatever.php'
you can define the document root directory of project and then, include all files depending on it
put
define(DOC_ROOT, realpath(direname(__FILE__));
in your front controller, and when you have to include a file
include(DOC_ROOT . "/includes/file.php");
all frameworks uses this method
I'd suggest using a relative path (eg ../style.css or ../../style.css)
The ../ references the parent directory to the current file.
This is what I do, in general.
I use root relative urls inside html (e.g. src="/images/logo.jpg"). This way I can just copy the html from one page and past it in another without having to worry about the link not working becase the other page is inside a folder.
I relative urls in css, because all the resources I use inside the css, like images, I keep in the same folder as the css file (or a sub-directory of it). I mostly do this because it is shorter (url(img/background.jpg); vs. url(/css/img/background.jpg);). Minor added bonus is you could just copy the css folder to create a new theme based on the old one, without having to change all the urls in the css.
In PHP I use include($_SERVER['DOCUMENT_ROOT'] . '/includes/mysql.php');. You can just copy past the code into another file in another folder and it will still work.
The only time I rarely need to hardcode paths is inside htaccess.

PHP highest directory

Sorry to bother you over something so trivial. I can't word the question properly to get a result on any search bar, I've tried google, and here, but got no related answers.
I'm currently setting up an include statement, and PHP files from different folders need to include the same files, namely "(Top directory)/public_html/Include/Head.php".
I'm not sure how to tell PHP to look for public_html in the top directory. I originally thought that was what ".." was for, but it seems to behave wierdly. Can somone please explain?
Here's what I'm using:
<?php include("../public_html/Include/Head.php") ?>
Also, include is a folder where I put all the files that users generally don't need to view, mainly to get them out of the way, and make my main folder less messy.
Define some global constant: define('TOP_DIR', '/www/') then use that in all your includes:
include(TOP_DIR.'public_html/Include/Head.php');
Put that define() in some easy to reach location and include it on any page you need. This stuff becomes much simpler if you use a framework that always has a single entry point like CodeIgniter. Then you can just have a file of constants and settings you include in your entry point file and you know that those things will always be available.
You could prepend with the doc root so that you have a consistent starting point and won't have to worry about traversing in your particular case, e.g.,
include($_SERVER['DOCUMENT_ROOT'].'/Include/Head.php')
or, for an application-wide solution, you could simply add Include to your include path:
set_include_path(get_include_path() . PATH_SEPARATOR . $_SERVER['DOCUMENT_ROOT'].'/Include');
http://php.net/manual/en/function.set-include-path.php
PHP's file importing is a bit weird, if you want to import relative to the file you want, use this instead:
<?php include(dirname(__FILE__) . "../Include/Head.php") ?>
The reason is that if you have a file in (Top directory)/public_html/myfile.php that includes this file, the relative includes will be relative to myfile.php and not the included file.
There are several things which affect what you're trying to accomplish.
First, absolute and relative paths. Any time you see directory navigation shortcuts in a path, you're working with a relative path. .. means to go up a directory, or to the parent directory.
Second, the concept of rooting or chrooting may apply. Depending on your system, the topmost directory / (or \) may or may not be where you are serving files from. As an example, you can set the topmost folder of a particular web site to be a specific folder in your filesystem (using Apache). This is considered "rooting" the web site to that folder. No user or browser can "see" files from its parent folders.
PHP, however, generally is not rooted to the same location as the web site.
If your PHP files are in multiple levels of folder, yet you need them to all include files from the same location, then you may want to use absolute paths.
The specifics of what your path should be are entirely system dependent.

How can I store and access SQLite databases from a central location?

I have installed SQLite on my UNIX system, and am planning on accessing it from PHP. However, the database is created in the directory I initialize it in, and if a script runs in a different directory a new database is created in the same directory.
Is there an option for SQLite (or the PHP wrappers) to create the databases in one location, and have those databases accessible just by name outside of that directory?
Ideally, I'd like to be able to do something like $db=new SQLiteDatabase("db.test"); in any directory and have it reference the same database, if that makes sense.
In order to always use the same database (which, afterall, is only a file), you'll have to use an absolute path.
Instead of using 'db.test', which is relative to the current directory, you'll have to use something like '/home/user/development/application/db.test'.
Note the / at the beginning of the path, which makes it absolute.
Of course, up to you to adapt this to your needs :-)
A good possibility, to not put a fully hard-coded path in your code, would be to use dirname(__FILE__) in one of your PHP files, to get the full absolute path to the directory containing that file, and build up from there, to get to your database's file.
You should probably store the absolute path somewhere in a config file that provides that data wherever needed. As said previously, you can use dirname(__FILE__) to get the absolute path to the directory in which the containing PHP script resides, so you can work from there.

Categories