php- Output directory does not exist - php

I am trying to save new file to my initial directory in my Symfony project but whatever I tried it throws:
Output directory does not exist
As I am sure that path exist a want to create a .txt file in it!
$path = "/var/www/app/web/uploads/my-file.txt";
$file = basename($path);
$txt = new File();
$txt->setSavePath($file);
$txt->save();
and:
public function setSavePath($savePath)
{
if (!is_dir($savePath)) {
throw \Exception("Output directory does not exist");
}
// Add trailing directory separator the save path
if (substr($savePath, -1) != DIRECTORY_SEPARATOR) {
$savePath .= DIRECTORY_SEPARATOR;
}
$this->savePath = $savePath;
}

Use dirname instead basename.
Because
$path = "/var/www/app/web/uploads/my-file.txt";
$file = basename($path);
// $file is `my-file.txt` and not the path `/var/www/app/web/uploads` you expect

You are checking if the $savePath is a directory is_dir, you are passing a file path, because of that your exception is thrown.
You should check is $savePath is a directory and its writable.
public function setSavePath($savePath)
{
if (!is_writable(dirname($savePath))) {
throw \Exception("Output directory does not exist or not writable.");
}
//... rest of code.
}
ref: http://php.net/is_dir
ref: http://php.net/is_writable

Related

PHP define the destination folder for an upload

I use the following PHP script to upload an image to my server. Actually it moves the file in the same folder where my script is (root). I would like to move it into the folder root/imageUploads. Thank you for your hints!
$source = $_FILES["file-upload"]["tmp_name"];
$destination = $_FILES["file-upload"]["name"];
...
if ($error == "") {
if (!move_uploaded_file($source, $destination)) {
$error = "Error moving $source to $destination";
}
}
You will need to check if the destination folder exists.
$destination = $_SERVER['DOCUMENT_ROOT'] . '/imageUploads/'
if (! file_exists($destination)) { // if not exists
mkdir($destination, 0777, true); // create folder with read/write permission.
}
And then try to move the file
$filename = $_FILES["file-upload"]["name"];
move_uploaded_file($source, $destination . $filename);
So now your destination looks like this:
some-file.ext
and it's dir is same as file that executes it.
You need to append some dir path to current destination. E.g.:
$path = __DIR__ . '/../images/'; // Relative to current dir
$path = '/some/path/in/server/images'; // Absolute path. Start with / to mark as beginning from root dir
And then move_uploaded_file($source, $path . $destination)
Full path to the destination folder should be provided to avoid and path issue for moving uploaded files, I have added three variations for destination paths below
$uploadDirectory = "uploads";
// Gives the full directory path of current php file
$currentPath = dirname(__FILE__);
$source = $_FILES["file-upload"]["tmp_name"];
// If uploads directory exist in current folder
// DIRECTORY_SEPARATOR gices the directory seperation "/" for linux and "\" for windows
$destination = $currentPath.DIRECTORY_SEPARATOR.$uploadDirectory.DIRECTORY_SEPARATOR.$_FILES["file-upload"]["name"];
if (!move_uploaded_file($source, $destination)) {
echo $error = "Error moving $source to $destination";
}
// If to current folder where php script exist
$destination = $currentPath.DIRECTORY_SEPARATOR.$_FILES["file-upload"]["name"];
if (!move_uploaded_file($source, $destination)) {
echo $error = "Error moving $source to $destination";
}
// If uploads directory exist outside current folder
$destination = $currentPath.DIRECTORY_SEPARATOR."..".DIRECTORY_SEPARATOR.$uploadDirectory.DIRECTORY_SEPARATOR.$_FILES["file-upload"]["name"];
if (!move_uploaded_file($source, $destination)) {
echo $error = "Error moving $source to $destination";
}

How to change name of every file in folder

I'm trying to change every file name in a folder, for e.g if file name is style.css than i want to rename it as style_[md5 value of style].css = style_a1b01e734b573fca08eb1a65e6df9a38.css
here is what I've tried
if ($handle = opendir("D:/web/htdocs/extra/css/")) {
while (false !== ($fileName = readdir($handle))) {
$path_parts = pathinfo($fileName);
$newName = md5($path_parts['filename']);
rename($fileName, $newName);
}
closedir($handle);
}
Where am i wrong?
errors are
Access is denied. (code: 5)
The system cannot find the file specified. (code: 2)
not sure the same happens on a windows, but on a GNU here …
if you printed out what you intend to do instead of trying bluntly you'd see some flaws:
rename( ., d41d8cd98f00b204e9800998ecf8427e)
rename( .., 5058f1af8388633f609cadb75a75dc9d)
when e.g. doing:
echo ("rename( ".$fileName.", ".$newName.")\n");
next thing to check maybe is rights to change files …
// DS to print \ the split between folder
define('DS',DIRECTORY_SEPARATOR);
// APP_PATH to get application path on the the server
define('APP_PATH',__DIR__.DS);
$oldname = APP_PATH.'css'.DS.'style.css';
/*
when you echo $oldname ,you will get the complete path of file
*/
// check the file is exists or No
if (file_exists($oldname)) {
$newName = md5($oldname);
/*add the extension of file that you will rename it */
rename($oldname, ($newName.'.css'));
}

Preserve the folder structure when creating a Zip archive

I want to create a zip file and copy all the folders and files from a directory to it. It is successfully created and contains the files and folders, but the file tree is not preserved, everything being in the root directory.
My directory:
folder/
test.txt
test2.txt
test.php
The zip archive:
folder/
test.txt
test2.txt
test.php
This is my code:
public function createZipFromDir($dir, $zip_file) {
$zip = new ZipArchive();
if(true !== $zip->open($zip_file, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)) {
return false;
}
$this->zipDir($dir, $zip);
return $zip;
}
public function zipDir($dir, $zip) {
$dir = rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
$files = scandir($dir);
foreach($files as $file) {
if(in_array($file, array('.', '..'))) continue;
if(is_dir($dir . $file)) {
$zip->addEmptyDir($file);
$this->zipDir($dir . $file, $zip);
} else {
$zip->addFile($dir . $file, $file);
}
}
}
$zip = $this->createZipFromDir($rootPath, $archiveName);
The issue is that when you create a folder or set the localname (second argument of addFile()) when adding a file to the archive, you only use $file, therefore everything gets put at the root. It is necessary to provide the file hierarchy as well.
Now the obvious solution would be to use $dir.$file instead, but this would only work properly on a folder located in the same directory as the script.
We actually need to keep track of two file trees:
the real tree, as it exists on the machine
the archive tree, relative to the path we want to archive
But since one is just a subset of the other, we can easily keep track of that by splitting the real path in two:
$dir, a prefix pointing to the original path
$subdir, a path relative to $dir
When referring to a file on the machine, we use $dir.$subdir and when referring to a file in the archive we use only $subdir. This requires us to adapt zipDir() to keep track of the prefix by adding a third argument to it and slightly modifying the call to zipDir() in createZipFromDir().
function createZipFromDir($dir, $zip_file) {
$zip = new ZipArchive();
if(true !== $zip->open($zip_file, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)) {
return false;
}
zipDir(
// base dir, note we use a trailing separator from now on
rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR,
// subdir, empty on initial call
null,
// archive ref
$zip
);
return $zip;
}
function zipDir($dir, $subdir, $zip) {
// using real path
$files = scandir($dir.$subdir);
foreach($files as $file) {
if(in_array($file, array('.', '..')))
continue;
// check dir using real path
if(is_dir($dir.$subdir.$file)) {
// create folder using relative path
$zip->addEmptyDir($subdir.$file);
zipDir(
$dir, // remember base dir
$subdir.$file.DIRECTORY_SEPARATOR, // relative path, don't forget separator
$zip // archive
);
}
// file
else {
// get real path, set relative path
$zip->addFile($dir.$subdir.$file, $subdir.$file);
}
}
}
This code has been tested and is working.

PHP ZipArchive is not adding any files (Windows)

I'm failing to put even a single file into a new zip archive.
makeZipTest.php:
<?php
$destination = __DIR__.'/makeZipTest.zip';
$fileToZip = __DIR__.'/hello.txt';
$zip = new ZipArchive();
if (true !== $zip->open($destination, ZIPARCHIVE::OVERWRITE)) {
die("Problem opening zip $destination");
}
if (!$zip->addFile($fileToZip)) {
die("Could not add file $fileToZip");
}
echo "numfiles: " . $zip->numFiles . "\n";
echo "status: " . $zip->status . "\n";
$zip->close();
The zip gets created, but is empty. Yet no errors are triggered.
What is going wrong?
It seems on some configuration, PHP fails to get the localname properly when adding files to a zip archive and this information must be supplied manually. It is therefore possible that using the second parameter of addFile() might solve this issue.
ZipArchive::addFile
Parameters
filename
The path to the file to add.
localname
If supplied, this is the local name inside the ZIP archive that will override the filename.
PHP documentation: ZipArchive::addFile
$zip->addFile(
$fileToZip,
basename($fileToZip)
);
You may have to adapt the code to get the right tree structure since basename() will remove everything from the path apart from the filename.
You need to give server right permission in folder where they create zip archive. You can create tmp folder with write permision chmod 777 -R tmp/
Also need to change destination where script try to find hello.txt file $zip->addFile($fileToZip, basename($fileToZip))
<?php
$destination = __DIR__.'/tmp/makeZipTest.zip';
$fileToZip = __DIR__.'/hello.txt';
$zip = new ZipArchive();
if (true !== $zip->open($destination, ZipArchive::OVERWRITE)) {
die("Problem opening zip $destination");
}
if (!$zip->addFile($fileToZip, basename($fileToZip))) {
die("Could not add file $fileToZip");
}
echo "numfiles: " . $zip->numFiles . "\n";
echo "status: " . $zip->status . "\n";
$zip->close()
check this class to add files and sub-directories in a folder to zip file,and also check the folder permissions before running the code,
i.e chmod 777 -R zipdir/
HZip::zipDir('/path/to/sourceDir', '/path/to/out.zip');
<?php
class HZip
{
private static function folderToZip($folder, &$zipFile, $exclusiveLength) {
$handle = opendir($folder);
while (false !== $f = readdir($handle)) {
if ($f != '.' && $f != '..') {
$filePath = "$folder/$f";
// Remove prefix from file path before add to zip.
$localPath = substr($filePath, $exclusiveLength);
if (is_file($filePath)) {
$zipFile->addFile($filePath, $localPath);
} elseif (is_dir($filePath)) {
// Add sub-directory.
$zipFile->addEmptyDir($localPath);
self::folderToZip($filePath, $zipFile, $exclusiveLength);
}
}
}
closedir($handle);
}
public static function zipDir($sourcePath, $outZipPath)
{
$pathInfo = pathInfo($sourcePath);
$parentPath = $pathInfo['dirname'];
$dirName = $pathInfo['basename'];
$z = new ZipArchive();
$z->open($outZipPath, ZIPARCHIVE::CREATE);
$z->addEmptyDir($dirName);
self::folderToZip($sourcePath, $z, strlen("$parentPath/"));
$z->close();
}
}

PHP file not uploading to localhost

I've set up an XAMPP server and trying to upload image files using a custom admin page. The page works fine when I set it up on a online server running ubuntu.
But when trying the same script in localhost gives me the following error.
Warning : move_upload_file(../img/products/fw000001.jpg) : failed to open stream. No such file or directory in C:\xampp\htdocs\OBS\store\kish\bin\functions.php on line 64
Here is the file upload part of functions.php
function upload_image($image,$code)
{
define("UPLOAD_DIR", "../img/products/");
if (!empty($image)) {
$myFile = $image;
if ($myFile["error"] !== UPLOAD_ERR_OK) {
return null;
}
//check if the file is an image
$fileType = exif_imagetype($_FILES["image"]["tmp_name"]);
$allowed = array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG);
if (!in_array($fileType, $allowed)) {
exit();
}
// ensure a safe filename
$name = $myFile["name"];
$parts = pathinfo($name);
$extension = $parts["extension"];
$savename = $code . "." . $extension;
// don't overwrite an existing file
$i = 0;
if(file_exists(UPLOAD_DIR . $savename)) {
unlink(UPLOAD_DIR . $savename);
}
// preserve file from temporary directory
$success = move_uploaded_file($myFile["tmp_name"],
UPLOAD_DIR . $savename);
if (!$success) {
exit();
}
else
{
return $savename;
}
// set proper permissions on the new file
chmod(UPLOAD_DIR . $name, 0644);
}
}
I'm not pretty sure about directory separator. Directory separator is represent with (/) on Linux based OS. Widows is using ( \ ) for directory separator. So, please change this line and tested it.
define("UPLOAD_DIR", "../img/products/");
to
define("UPLOAD_DIR", "..".DIRECTORY_SEPARATOR."img".DIRECTORY_SEPARATOR."products".DIRECTORY_SEPARATOR.");
Change this line
// preserve file from temporary directory
$success = move_uploaded_file($_FILES["image"]["tmp_name"],UPLOAD_DIR . $savename);

Categories