PharData zip to include empty folders - php

I am zipping entire server content(for backup purposes) via php / PharData:
$phar = new PharData(SYS_ROOT.'/project.zip');
$phar->buildFromDirectory(SYS_ROOT.'/');
SYS_ROOT is constant defining path to web root (. dot in this case). Everything works fine except for missing empty folders in the resulting zip. The folders are necessary.
I tought about Phar::addEmptyDir, but that would require another iteration through the folders to determine which are empty. Tried recursivedirectoryiterator to no avail(also skipped empty folders) as well :(

I've never used this but looking at the documentation it says the following:
Phar::buildFromDirectory — Construct a phar archive from the files within a directory.
Which means that it is behaving as expected. However I think you could use buildFromIterator and then also compress since this is for backups I think I'd go with that one.

Related

What filepath to use with ffmpeg_php?

I'm using ffmpeg-php to extract thumbnails from user uploaded videos for a site I'm building. Previously the videos were stored in a subdirectory of the directory containing the relevant php files and it worked fine. However I have now altered my directory structure and can't work out what filepath to supply ffmpeg_movie() with. The relevant files are:
/app/classes/class_lib.php
location of the class that calls ffmpeg_movie() and extracts/saves the thumbnail.
/app/upload.php
the php file that requires the above class, instantiates it and calls the relevant method.
And the videos are stored in:
/videos/encodes/
All those paths are relative to the sites public root (public_html). I have trieda number of different paths but keep getting a "cannot open movie file [Attempted video path]". I've tried paths relative to the site root /video/encodes/movie.mp4, relative to the executed php file ../video/encodes/movie.mp4, relative to the php class file ../../video/encodes/movie.mp4 and even the server root /srv/www/sitename.com/public_html/video/encodes/movie.mp4. No luck with any of them.
Any other ideas?
Server is Apache running on Ubuntu and directory permissions haven't changed since it was previously working (the encodes folder is globally readable)
I've ended up using the full url http://somesite.com/video/encodes/movie.mp4. It actually works, but it feels like the wrong way to do it. Unfortunately nothing else seems to work.
Still, if you're having the same problem then this is at least a working solution.

Weird behaviour of rename() in PHP

I am having a weird problem with my php. Whenever I try to move a file with rename(), not only the file is not moved, but also the directory to which it should be copied is deleted, together with all files within it. The original code is:
rename('temp.odt', 'tmp/report.odt');
but I have already tried other path delimiters like
rename('temp.odt', 'tmp\report.odt');
rename('temp.odt', 'tmp\\report.odt');
rename('temp.odt', 'tmp' . DIRECTORY_SEPARATOR . 'report.odt');
rename('C:\wamp\www\zaiko\temp.odt', 'C:\wamp\www\zaiko\tmp\report.odt');
all to no avail. The code comes from a 3rd-party module which is used in the system I am working on.
Points well checked:
The file 'temp.odt' does exist in the current directory;
The directory 'tmp' does exist and there are several files in it. Also it is not read only.
The target file does not already exist (the actual file name has a timestamp, I reduced it here for simplicity)
After running rename(), the 'temp.odt' file is intact in its original location, while the folder 'tmp' is vanished as well as everything inside it. The following warning is issued:
( ! ) Warning: rename(temp.odt,tmp\report.odt) [function.rename]: The system couldn't find the specified path*. (code: 3) in C:\wamp\www\zaiko\modules\mod_deliver.php on line 192
*translated from Portuguese
Running: Apache 2.2.17 with PHP 5.3.5 on Windows XP with NTFS
Editing:
Just found the cause of the problem. It turns out that the module used by the application uses, in turn, a compression library; this library uses a temporary folder with exactly the same name as the one used by the application.
It must use some sort of cache, which would explain why the error didn't appear 100% times.
Problem solved by changing the name of the 'tmp' folder to anything else.
Thank you all for your time, and sorry for bothering you with such a stupid thing that, as it turns out, had absolutely nothing to do with my initial guess and, consequently, with the question formulated.
The example on PHP.net tells you exactly what to do - use the ROOT PATH to the file - normally this can be got by using $_SERVER['DOCUMENT_ROOT'] (but this only goes to the htdocs/public_html directory - you need to specify the rest) or by manually typing the path in (but try to avoid this).
<?php
rename("/tmp/tmp_file.txt", "/home/user/login/docs/my_file.txt");
?>
At a guess, the following should work (assuming this is your path) - this also checks that your file actually exists so it can be renamed - you need to make sure that tmp/ actually exists in the first place, but you will get an error popping out if it didn't:
<?php
$root = getcwd().DIRECTORY_SEPARATOR; // Obtain the current working dir
$srcpath = $root."temp.odt"; // The file you want to rename
$destpath = $root."tmp/report.odt"; // Where you want to rename the file to
// make sure file exists and its movable
if(is_writable($srcpath)){
// if it exists, rename it
rename($srcpath, $dstpath);
echo "File was renamed!";
} else {
echo "It seems that the specified file doesn't exist!";
}
?>
You were escaping characters by using backslashes - always use forward slashes (I know this is within a single quote, which is ok, but if you use double quote then you would wonder what's gone wrong)!

Include files from parent or other directory

I'm needing to include a file from the parent directory, and other sub-directories, into a sub-directory. I've done it before by simply using include('/rootdirectory/file.php'); but now it won't seem to work.
Just wondering how I can do this, thanks.
Here's my exact line:
include('/forums/groups.php');
It's giving me this error(the page still runs):
Warning: include(/forums/groups.php) [function.include]: failed to
open stream: No such file or directory in
C:\xampp\htdocs\forums\blog\posts.php on line
Warning: include() [function.include]: Failed opening
'/forums/groups.php' for inclusion
(include_path='.;C:\xampp\php\PEAR') in
C:\xampp\htdocs\forums\blog\posts.php on line 3
include() and its relatives take filesystem paths, not web paths relative to the document root. To get the parent directory, use ../
include('../somefilein_parent.php');
include('../../somefile_2levels_up.php');
If you begin with a /, an absolute system file path will be used:
// Full absolute path...
include('/home/username/sites/project/include/config.php');
If your server is not resolving the file from the parent directory using
include '../somefilein_parent.php'
try this (using the parent directory relative to the script):
include __DIR__ . "/../somefilein_parent.php";
Here's something I wrote with that problem in mind:
<?
function absolute_include($file)
{
/*
$file is the file url relative to the root of your site.
Yourdomain.com/folder/file.inc would be passed as
"folder/file.inc"
*/
$folder_depth = substr_count($_SERVER["PHP_SELF"] , "/");
if($folder_depth == false)
$folder_depth = 1;
include(str_repeat("../", $folder_depth - 1) . $file);
}
?>
hope it helps.
Depends on where the file you are trying to include from is located.
Example:
/rootdir/pages/file.php
/someotherDir/index.php
If you wrote the following in index.php:
include('/rootdir/pages/file.php');it would error becuase it would try to get:
/someotherDir/rootdir/pages/file.php Which of course doesn't exist...
So you would have to use include('../rootdir/pages/file.php');
In laymans terms, and practicality, I see this as an old DOS trick/thing. Whoa! What was that? DOS? Never heard of it!
".." backs you out of the current sub-directory one time to a higher folder/directory, and .. enter typed twice backs you out too 2 higher parent folders. Keep adding the ".. enter" back to back and you will soon find yourself at the top level of the directory.
As for Newbies to understand this better, consider this (in terms of the home PC or "C:\ drive" if you know what that means, rather than the web-servers/host "root directory" ). While your at it, Consider your website existing somewhere on your home PC's hard drive, buried in some folder under the C:\ drive. Lastly, you can think of it as ".." is back one directory and "/" is forward one directory/folder.
Now!
If you are using the command prompt and are within the "myDocuments" folder of your PC you must back out of that folder to get closer to the higher directory "C:\" by typing the "../".
If you wanted to access a file that is located in the widows directory while you are still in the myDocuments folder you would theoretically type ../windows; in reality of DOS command prompt you would simply type .., but I am setting you up for the web. The / redirects forward to another directory naturally.
Using "myDocuments" lets pretend that you created 2 folders within it called "PHP1" and "PHP2", in such we now have the folders:
C:\myDocuments\PHP1
C:\myDocuments\PHP2
In PHP1 you place a file called index.php. and in PHP2 folder you placed a file called Found.php. it now becomes:
C:\myDocuments\PHP1\index.php
C:\myDocuments\PHP2\found.php
Inside the
C:\myDocuments\PHP1\index.php file you would need to edit and type something like:
<?php include ('../php2/found.php')?>
The ../ is positional thus it considers your current file location "C:\myDocuments\PHP1\index.php" and is a directive telling it to back out of PHP1 directory and enter or move forward into PHP2 directory to look for the Found.php file. But does it read it? See my thoughts on trouble shooting below.
Now! suppose you have 1 folder PHP1 and a sub-folder PHP2:
C:\myDocuments\PHP1\PHP2
you would simply reference/code
<?php include('/PHP2/found.php') ?>
as PHP2 exist as a sub-directory, below or within PHP1 directory.
If the above does not work it may have something to do with access/htaccess or permission to the directory or a typo. To enhance this...getting into trouble shooting...If the "found.php" file has errors/typo's within it, it will crash upon rendering at the error, such could be the reason (require/require_once) that you are experiencing the illusion that it is not changing directories or accessing the file.
At last thought on the matter, you may need to instantiate your functions or references in order to use the included/require "whatever" by creating a new variable or object such as
$newObject = new nameobject("origianlThingy");
Remember, just because you are including/requiring something, sometimes means just that, it is included/required to run, but it might need to be recreated to make it active or access it. New will surely re-create an instance of it "if it is readable" and make it available within the current document while preserving the original. However you should reference the newly created variable $newObject in all instances....if its global.
To put this in perspective of some web host account; the web host is some whopping over sized hard-drive (like that on your PC) and your domain is nothing more than a folder they have assigned to you. Your folder is called the root. Inside that folder you can do anything you are allowed to do.
your "one of many ways" to move between directories/folders is to use the ../ however many times to back out of your current in reference to folder position you want to find.
In my drunken state I realize that I know too much to be sane, and not
enough to be insane!"
Any path beginning with a slash will be an absolute path. From the root-folder of the server and not the root-folder of your document root. You can use ../ to go into the parent directory.
You may interest in using php's inbuilt function realpath().
and passing a constant DIR
for example:
$TargetDirectory = realpath(__DIR__."/../.."); //Will take you 2 folder's back
String realpath() :: Returns canonicalized absolute pathname ..
I took inspiration from frank and I added something like this in my "settings.php" file that is then included in all pages when there is a link:
"settings.php"
$folder_depth = substr_count($_SERVER["PHP_SELF"] , "/");
$slash="";
for ($i=1;$i<=($folder_depth-2);++$i){
$slash= $slash."../";
}
in my header.php to be included in all pages:
a href= .... php echo $slash.'index.php'....
seems it works both on local and hosted environment....
(NOTE: I am an absolute beginner )
Had same issue earlier solved like this :
include('/../includes/config.php'); //note '/' appearing before '../includes/config.php'
the root directory (in PHP) is the directory of the file that is pinged. For example, I go to http://localhost/directory/to/file/index.php, the root directory will be "/dictory/to/file", since it's the one that you've made a web request for.
I can't believe none of the answers pointed to the function dirname() (available since PHP 4).
Basically, it returns the full path for the referenced object. If you use a file as a reference, the function returns the full path of the file. If the referenced object is a folder, the function will return the parent folder of that folder.
https://www.php.net/manual/en/function.dirname.php
For the current folder of the current file, use $current = dirname(__FILE__);.
For a parent folder of the current folder, simply use $parent = dirname(__DIR__);.
If your configuration file PHP.ini is set up correctly then you can use:
include($_SERVER["DOCUMENT_ROOT"]."/my_script.php");
// or
require($_SERVER["DOCUMENT_ROOT"]."/my_script.php");

PHP include path sub-folder files not included

I have a site where the PHP include path is /usr/share/php
Within this path I have a sub-folder containing some utility files, e.g. /usr/share/php/utils. my_session.php is one of these utility files.
My application calls
require ("my_session.php");
and this works even though the file is actually within the utils folder.
I am trying to replicate this site in another installation and I am getting the error:
Failed opening required 'my_session.php' (include_path='.:/usr/share/php)
My question is:
Should the php include path also include files in sub-folders in the include path?
This appears to be the case on my original site and I don't know why the behaviour seems to be different on the second site.
According to PHP documentation when you try to include a file, only paths listed in the include_path directive are checked. PHP is not supposed to check their subfolders.
My guess would be that this fails because you are using a relative path for the require.
Your include_path is defined as .:/usr/share/php. That means only two folders will be checked when require('my_session.php') gets executed:
the current path
the folder /usr/share/php
I don't know your folder structure, so let's just imagine one:
my_project
- app
-- index.php
- lib
-- my_session.php
Now, if my_project/app/index.php tries to require('my_session.php') this will fail, because the current folder at the time executing the require is my_project/app/ and there is no file entry of my_session.php relative to my_project/app/ (it's relative to my_project/lib/ instead).
Long story short: Try to to use an absolute path instead of your relative one, e.g.
require('/var/www/html/my_project/lib/my_session.php');
Edit: removed and its subfolders, which was wrong. Too much __autoload in my brain^^
Two solutions:
Add /usr/share/php/utils to your include_path.
or
Include your file with require ("utils/my_session.php");

Creating a file/folder structure and zipping it up?

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.

Categories