CodeIgniter - Message: mkdir(): Permission denied on Ubuntu - php

I'd like some help please. I have this PHP script inside my Post_model constructor
$dir = FCPATH . 'uploads' . DIRECTORY_SEPARATOR . 'posts';
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
which shows me this error:
Severity: Warning
Message: mkdir(): Permission denied
The main idea is that the project has the ability to create users and these users can upload images, or create folders-albums which are stored in the uploads folder.
I've been struggling to fix this error the last days and can't find a solution. I have tried this code and on Windows and works great, but not on Linux (Ubuntu 14.04)

Please try chmod 777 -R . in your directory

Even i had same problem , i tried with umask, it worked. you can do like this,
$old = umask(0);
mkdir($dir, 0755, true);
umask($old);

[How to Create Directory in PHP / CodeIgniter]
(http://codedpoint.16mb.com/index.php/viewCode?topic=Create%20Directory%20-%20CodeIgnitor)

I suggest you manually create 'uploads' folder and give it 777 permission (not recursive) and then in your php script do the following:
if(!is_dir('./uploads/posts')) //create the folder if if does not already exists
{
mkdir('./uploads/posts',0755,TRUE);
}
by this, every time your script tries to create a new directory, it will have the permission to do so since you are creating the new directory inside uploads which has 777.

the issue probably is the mask :)
if (!function_exists('mkdir_r')) {
/**
* create directory recursively
* #param $dirName
* #param int $rights
* #param string $dir_separator
* #return bool
*/
function mkdir_r($dirName, $rights = 0744, $dir_separator = DIRECTORY_SEPARATOR) {
$dirs = explode($dir_separator, $dirName);
$dir = '';
$created = false;
foreach ($dirs as $part) {
$dir .= $part . $dir_separator;
if (!is_dir($dir) && strlen($dir) > 0) {
$created = mkdir($dir, $rights);
}
}
return $created;
}
}
if (!function_exists('ensure_dir')) {
/**
* ensure directory exist if not create
* #param $dir_path
* #param int $mode
* #param bool $use_mask
* #param int $mask
* #return bool
*/
function ensure_dir($dir_path, $mode = 0744, $use_mask = true, $mask = 0002) {
// set mask
$old_mask = $use_mask && $mask != null
? umask($mask)
: null;
try {
return is_dir($dir_path) || mkdir_r($dir_path, $mode);
} finally {
if ($use_mask && $old_mask != null) {
// restore original
umask($old_mask);
}
}
}
}

Related

Extract ZIP file, including hidden files

I'm using ZipArchive and I want to extract ZIP file.
I can see a comment in the docs for ZipArchive::extractTo:
Note, in Linux (possibly other *nix platforms too) there is no way to extract hidden files ( aka filename starting with a '.') from a Zip archive.
And very important note: I need it to work on both *nix and Windows platforms.
So how to properly extract ZIP file into dir, including hidden files?
Thanks in advance,
JK.
You could use the system() or exec() functions if the server allows them :
system("unzip archive.zip");
There are although shell_exec() and passthru().
Hope it helps.
EDIT
Since OP looking for pure-php solution here is a user implemented function for php manual (Zip Functions) :
<?php
/**
* Unzip the source_file in the destination dir
*
* #param string The path to the ZIP-file.
* #param string The path where the zipfile should be unpacked, if false the directory of the zip-file is used
* #param boolean Indicates if the files will be unpacked in a directory with the name of the zip-file (true) or not (false) (only if the destination directory is set to false!)
* #param boolean Overwrite existing files (true) or not (false)
*
* #return boolean Succesful or not
*/
function unzip($src_file, $dest_dir=false, $create_zip_name_dir=true, $overwrite=true)
{
if ($zip = zip_open($src_file))
{
if ($zip)
{
$splitter = ($create_zip_name_dir === true) ? "." : "/";
if ($dest_dir === false) $dest_dir = substr($src_file, 0, strrpos($src_file, $splitter))."/";
// Create the directories to the destination dir if they don't already exist
create_dirs($dest_dir);
// For every file in the zip-packet
while ($zip_entry = zip_read($zip))
{
// Now we're going to create the directories in the destination directories
// If the file is not in the root dir
$pos_last_slash = strrpos(zip_entry_name($zip_entry), "/");
if ($pos_last_slash !== false)
{
// Create the directory where the zip-entry should be saved (with a "/" at the end)
create_dirs($dest_dir.substr(zip_entry_name($zip_entry), 0, $pos_last_slash+1));
}
// Open the entry
if (zip_entry_open($zip,$zip_entry,"r"))
{
// The name of the file to save on the disk
$file_name = $dest_dir.zip_entry_name($zip_entry);
// Check if the files should be overwritten or not
if ($overwrite === true || $overwrite === false && !is_file($file_name))
{
// Get the content of the zip entry
$fstream = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
file_put_contents($file_name, $fstream );
// Set the rights
chmod($file_name, 0777);
echo "save: ".$file_name."<br />";
}
// Close the entry
zip_entry_close($zip_entry);
}
}
// Close the zip-file
zip_close($zip);
}
}
else
{
return false;
}
return true;
}

mkdir always sets folders to read-only?

i am trying to create folders from within php. Whenever i use the mkdir function with permission 0777 i get a read-only folder. I want this folder to be read & write.
The parent folder (drive/) is fully writable and readable for every user.
This is what i use: mkdir(ABSPATH . 'drive/' . $folderName, 0777);
I have also tried to use it without any additional paramaters: mkdir(ABSPATH . 'drive/' . $folderName);
Any ideas why this is and how to fix this so that i can generate folders that has write access?
In a shared environment, mkdir fails to set the permissions properly. A workaround is to set the chmod with chmod() after you've created the directory.
You can have write permission too with mkdir..Here is the code
<?php
$dir = 'myDir';
// create new directory with 744 permissions if it does not exist yet
// owner will be the user/group the PHP script is run under
if ( !file_exists($dir) ) {
mkdir ($dir, 0744);
}
file_put_contents ($dir.'/test.txt', 'Hello File');
Found the source from here
the issue probably is the mask :)
if (!function_exists('mkdir_r')) {
/**
* create directory recursively
* #param $dirName
* #param int $rights
* #param string $dir_separator
* #return bool
*/
function mkdir_r($dirName, $rights = 0744, $dir_separator = DIRECTORY_SEPARATOR) {
$dirs = explode($dir_separator, $dirName);
$dir = '';
$created = false;
foreach ($dirs as $part) {
$dir .= $part . $dir_separator;
if (!is_dir($dir) && strlen($dir) > 0) {
$created = mkdir($dir, $rights);
}
}
return $created;
}
}
if (!function_exists('ensure_dir')) {
/**
* ensure directory exist if not create
* #param $dir_path
* #param int $mode
* #param bool $use_mask
* #param int $mask
* #return bool
*/
function ensure_dir($dir_path, $mode = 0744, $use_mask = true, $mask = 0002) {
// set new mask
$old_mask = $use_mask && $mask != null
? umask($mask)
: null;
try {
return is_dir($dir_path) || mkdir_r($dir_path, $mode);
} finally {
if ($use_mask && $old_mask != null) {
// restore original mask
umask($old_mask);
}
}
}
}

Move and delete a file from two servers

At work, we have a website on which we publish PDF files which are available for download (mostly user notices etc.). We also manage our internal database for updates and to generate CD's and USB Sticks with all PDF files on it, which are shipped out with the products.
So I build a platform where all plants that produce these PDF files can upload them. From time to time, a person will take care of updating the system (sync both servers).
I would like to have a link next to the files with a delete option. I already have that using a simple php script.
<?php
$deleter = new Deleter("./");
class Deleter {
var $filename;
var $ignorelist = array (
'.',
'..',
'index.php',
'del.php',
'deletefile.php'
);
function Deleter($path="./") {
$this->__construct($path);
}
function __construct($path="./") {
$this->filename = basename(__FILE__);
array_push($this->ignorelist, $this->filename);
// insert page header
$this->createHeader();
// condition: create initial file list?
if (isset($_GET['delete']) && !empty($_GET['delete'])) {
// a path has been set, escape and use
$path = basename($_GET['delete']);
$path = urldecode($path);
//$path = mysql_real_escape_string($path);
// condition : Step 2: seek deletion confirmation?
if (!isset($_GET['confirm']) || $_GET['confirm'] != 'aye') {
$this->createConfirmationStep($path);
// step 3: delete!
} else {
$this->createShowDelete($path);
}
// step 1: no files selected, create file list
} else {
echo '
<p>These files are on the server:</p>
<ul>
';
$this->createFileList($path);
echo '</ul>';
}
// insert page footer
$this->createFooter();
}
/**
* Step 1: Create a list of all files within a specific directory
*
* #param string $path The server path to look for files in
* #return array $fileList Array of all files, with file/directory details
* #access public
*/
function createFileList($path) {
// condition : if the path isn't set, assume one
if (!isset($path)) {
$path = "./";
}
// temporary arrays to hold separate file and directory content
$filelist = array();
$directorylist = array();
// get the ignore list, in local scope
$ignorelist = $this->ignorelist;
// Open directory and read contents
if (is_dir($path)) {
// loop through the contents (PHP4 compat)
$dh = opendir($path);
while (false !== ($file = readdir($dh))) {
// skip over any files in the ignore list
if (!in_array($file, $ignorelist)) {
// condition : if it is a directory, add to dir list array
if (is_dir($path.$file)) {
$directorylist[] = array(
"path" => $path,
"file" => $file,
"filetype" => 'directory',
"date" => date("M d Y, H:i", filemtime($path.$file."")),
"filecount" => $this->countRelevantFiles($path.$file),
"filesize" => 0
);
// file, add to file array
} else {
$filelist[] = array(
"path" => $path,
"file" => $file,
"filetype" => $this->getFileType($path.$file) . " file",
"date" => date("M d Y, H:i", filemtime($path.$file."")),
"filecount" => 0,
"filesize" => $this->getFileSize(filesize($path.$file))
);
}
}
}
}
// merge file and directory lists
$finalList = array_merge($directorylist, $filelist);
// loop through each file
foreach ($finalList as $key => $value) {
// condition : add trailing slash for directories
$trailingslash = ($value['filetype'] == 'directory' ) ? '/' : '';
// condition : if it is a directory, display count of subfiles
if ($value['filetype'] == 'directory') {
$fileending = ($value['filecount'] == 1) ? 'item' : 'items';
$filedetails = ' (contains '.$value['filecount'].' '.$fileending.')';
// else, if it is a file, display file size
} else {
$filedetails = ' ('.$value['filesize'].')';
}
// create the html for each project
echo '
<li class="' . $value['filetype'].'" id="file_' . urlencode($value['file']) . '">
<strong>' . $value['file'] . '</strong> /
';
echo '
<a href="./'.$this->filename.'?delete='.urlencode($value['file'].$trailingslash).'">
Delete
</a>
</li>
';
}
}
/**
* count the number of files in a directory, not including the list of ignorable files
*
* #param string $path The server path to look for files in
* #return int $count The number of relevant files
* #access private
*/
function countRelevantFiles($path, $count = 0) {
// open the directory
if (is_dir($path)) {
// loop through all files, checking if we should count the current one
$dh = opendir($path);
while (false !== ($file = readdir($dh))) {
if (!in_array($file, $this->ignorelist)) {
$count++;
if(is_dir($path."/".$file)) {
$count = $this->countRelevantFiles($path."/".$file, $count);
}
}
}
}
// return the result
return $count;
}
/**
* list all sub-files of a directory
*
* #param string $path The server path to look for files in
* #return void
* #access private
*/
function listFilesToDelete($path) {
// open the directory
if (is_dir($path)) {
// loop through all files, checking if we should count the current one
$dh = opendir($path);
while (false !== ($file = readdir($dh))) {
if (!in_array($file, $this->ignorelist)) {
echo '<li>'.$path.'/'.$file.'</li>';
if(is_dir($path."/".$file)) {
$this->listFilesToDelete($path."/".$file);
}
}
}
}
}
/**
* Delete files
*
* #param string $path The server path to delete
* #return void
* #access private
*/
function delete($path) {
// Simple delete for a file
if (is_file($path)) {
echo '<li>deleting file: ' . $path . '</li>';
if (copy($path, "../trash/".$path)) {
unlink($path);
}
}
}
/**
* Create a nice readable filesize from the number of bytes in a file
*
* #param int $size the size in bytes
* #param string $retstring
*
* #return string the size in nice words
*/
function getFileSize($size, $retstring = null)
{
$sizes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
if ($retstring === null) { $retstring = '%01.2f %s'; }
$lastsizestring = end($sizes);
foreach ($sizes as $sizestring) {
if ($size < 1024) { break; }
if ($sizestring != $lastsizestring) { $size /= 1024; }
}
if ($sizestring == $sizes[0]) { $retstring = '%01d %s'; } // Bytes aren't normally fractional
return sprintf($retstring, $size, $sizestring);
}
/**
* Function to find a file type for a given filename
*
* #param string $file filename/path
* #return string $extension file type
*/
function getFileType($file="") {
// get file name
$filearray = explode("/", $file);
$filename = array_pop($filearray);
// condition : if no file extension, return
if(strpos($filename, ".") === false) return false;
// get file extension
$filenamearray = explode(".", $filename);
$extension = $filenamearray[(count($filenamearray) - 1)];
return $extension;
}
/* Page Building Methods */
/**
* Create page header
*/
function createHeader(){
echo '
';
}
/**
* Create page footer
*/
function createFooter(){
echo '
';
}
/**
* Create confirmation step
*/
function createConfirmationStep($path){
echo '
<p>� back to file list</p>
<p>Please confirm that you want to delete the following files:</p>
<p class="confirm">Delete</p>
<ol>
<li>'.$path.'</li>
';
$this->listFilesToDelete($path);
echo '
</ol>
<p class="confirm">Delete</p>
';
}
/**
* Show the files you're deleting
*/
function createShowDelete($path){
echo '
<p>� back to file list</p>
<p>The following items have been removed:</p>
<ol>
';
$this->delete($path);
echo '
</ol>
<p><strong>Deletion complete.</strong></p>
<p>� back to file list</p>
';
}
}
?>
Now what I would like this to do is delete a file on one server e.g. server1.com/files/ and move the same file from server2.com/files/ to server2.com/trash/
I have full access to both servers. Is there any way to do that?
since you didn't tell us on what OS you're running you php script, I'm assuming you have a linux.
since you need to do that from one server, you'd need to have a passwordless ssh access to the other server. then you'd need to create a bash script that utilizes mv and rsync to do the file manipulations you need. and then you can use php's exec() function to execute and send the filename param to the shell script from a web page.
I think it's better to configure rsync over ssh with --delete option. Something like this
/usr/bin/rsync -avz --delete /path/files -e "ssh" userforsync#$SECONDARYSERVER:/path/files
where is $SECONDARYSERVER is dns name or ip. To make this work you should accept authentication by public key on secondary server and add public key to authorized keys

How to create a directory in Live Server using PHP?

<?php
$dirPath = "Admin/new_images";
$result = mkdir($dirPath, 0777);
if ($result == 1) {
echo $dirPath . " has been created";
} else {
echo $dirPath . " has NOT been created";
}
?>
This code is working fine with my Local Host.
But its not working on live server.
Can anyone help me on this?
try this:
<?php
$dirPath = "Admin/new_images";
$result = mkdir($dirPath, 0777, true);
chmod($dirPath, 0777);
if ($result == 1) {
echo $dirPath . " has been created";
} else {
echo $dirPath . " has NOT been created";
}
?>
for window u have to change $dirPath like below:
$dirPath = "Admin\\new_images";
mkdir — Makes directory
Description
bool mkdir ( string $pathname [, int $mode = 0777 [, bool $recursive = false [, resource $context ]]] )
Attempts to create the directory specified by pathname.
Parameters :
pathname The directory path.
mode The mode is 0777 by default, which means the widest possible
access. For more information on modes, read the details on the chmod()
page.
Note:
mode is ignored on Windows.
Note that you probably want to specify the mode as an octal number,
which means it should have a leading zero. The mode is also modified
by the current umask, which you can change using umask().
recursive Allows the creation of nested directories specified in the
pathname. Defaults to FALSE.
context Note: Context support was added with PHP 5.0.0. For a
description of contexts, refer to Stream Functions
Return Values
Returns TRUE on success or FALSE on failure.
<?php
/**
* Makes directory, returns TRUE if exists or made
*
* #param string $pathname The directory path.
* #return boolean returns TRUE if exists or made or FALSE on failure.
*/
function mkdir_recursive($pathname, $mode)
{
is_dir(dirname($pathname)) || mkdir_recursive(dirname($pathname), $mode);
return is_dir($pathname) || #mkdir($pathname, $mode);
}
?>
Try the below code
<?php
test();
function test(){
$root_path = $_SERVER['DOCUMENT_ROOT'];
$directory_name = 'testDir';
if (!file_exists($root_path.'/'.$directory_name)) {
if(mkdir($root_path.'/'.$directory_name, 0777, true)){
print "Directory created successfully.";
}else{
print "Error in creating Directory.";
}
}else{
print "Directory already exists.";
}
}
?>

What is the best way to resolve a relative path (like realpath) for non-existing files?

I'm trying to enforce a root directory in a filesystem abstraction. The problem I'm encountering is the following:
The API lets you read and write files, not only to local but also remote storages. So there's all kinds of normalisation going on under the hood. At the moment it doesn't support relative paths, so something like this isn't possible:
$filesystem->write('path/to/some/../relative/file.txt', 'file contents');
I want to be able to securely resolve the path so the output is would be: path/to/relative/file.txt.
As is stated in a github issue which was created for this bug/enhancement (https://github.com/FrenkyNet/Flysystem/issues/36#issuecomment-30319406) , it needs to do more that just splitting up segments and removing them accordingly.
Also, since the package handles remote filesystems and non-existing files, realpath is out of the question.
So, how should one go about when dealing with these paths?
To quote Jame Zawinski:
Some people, when confronted with a problem, think "I know, I'll use regular expressions."
Now they have two problems.
protected function getAbsoluteFilename($filename) {
$path = [];
foreach(explode('/', $filename) as $part) {
// ignore parts that have no value
if (empty($part) || $part === '.') continue;
if ($part !== '..') {
// cool, we found a new part
array_push($path, $part);
}
else if (count($path) > 0) {
// going back up? sure
array_pop($path);
} else {
// now, here we don't like
throw new \Exception('Climbing above the root is not permitted.');
}
}
// prepend my root directory
array_unshift($path, $this->getPath());
return join('/', $path);
}
I've resolved how to do this, this is my solution:
/**
* Normalize path
*
* #param string $path
* #param string $separator
* #return string normalized path
*/
public function normalizePath($path, $separator = '\\/')
{
// Remove any kind of funky unicode whitespace
$normalized = preg_replace('#\p{C}+|^\./#u', '', $path);
// Path remove self referring paths ("/./").
$normalized = preg_replace('#/\.(?=/)|^\./|\./$#', '', $normalized);
// Regex for resolving relative paths
$regex = '#\/*[^/\.]+/\.\.#Uu';
while (preg_match($regex, $normalized)) {
$normalized = preg_replace($regex, '', $normalized);
}
if (preg_match('#/\.{2}|\.{2}/#', $normalized)) {
throw new LogicException('Path is outside of the defined root, path: [' . $path . '], resolved: [' . $normalized . ']');
}
return trim($normalized, $separator);
}
./ current location
../ one level up
function normalize_path($str){
$N = 0;
$A =explode("/",preg_replace("/\/\.\//",'/',$str)); // remove current_location
$B=[];
for($i = sizeof($A)-1;$i>=0;--$i){
if(trim($A[$i]) ===".."){
$N++;
}else{
if($N>0){
$N--;
}
else{
$B[] = $A[$i];
}
}
}
return implode("/",array_reverse($B));
}
so:
"a/b/c/../../d" -> "a/d"
"a/./b" -> "a/b"
/**
* Remove '.' and '..' path parts and make path absolute without
* resolving symlinks.
*
* Examples:
*
* resolvePath("test/./me/../now/", false);
* => test/now
*
* resolvePath("test///.///me///../now/", true);
* => /home/example/test/now
*
* resolvePath("test/./me/../now/", "/www/example.com");
* => /www/example.com/test/now
*
* resolvePath("/test/./me/../now/", "/www/example.com");
* => /test/now
*
* #access public
* #param string $path
* #param mixed $basePath resolve paths realtively to this path. Params:
* STRING: prefix with this path;
* TRUE: use current dir;
* FALSE: keep relative (default)
* #return string resolved path
*/
function resolvePath($path, $basePath=false) {
// Make absolute path
if (substr($path, 0, 1) !== DIRECTORY_SEPARATOR) {
if ($basePath === true) {
// Get PWD first to avoid getcwd() resolving symlinks if in symlinked folder
$path=(getenv('PWD') ?: getcwd()).DIRECTORY_SEPARATOR.$path;
} elseif (strlen($basePath)) {
$path=$basePath.DIRECTORY_SEPARATOR.$path;
}
}
// Resolve '.' and '..'
$components=array();
foreach(explode(DIRECTORY_SEPARATOR, rtrim($path, DIRECTORY_SEPARATOR)) as $name) {
if ($name === '..') {
array_pop($components);
} elseif ($name !== '.' && !(count($components) && $name === '')) {
// … && !(count($components) && $name === '') - we want to keep initial '/' for abs paths
$components[]=$name;
}
}
return implode(DIRECTORY_SEPARATOR, $components);
}

Categories