This is what I've got so far. I need to be able to apply 0666 to all the files in the archive. Can't I do that as I am exporting? What is a sample code for changing the chmod during unarchiving or after unarchiving?
$zip = new ZipArchive;
if ($zip->open('upload/'. $username . $file_ext) === TRUE) {
$zip->extractTo('dir/' . $username);
$zip->close();
} else {
echo 'failed';
}
Thanks for all of the help!
Brandon
Setting 0666 on directories might not be what you want ;-)
File creation in any process in Linux will use with 0777 for directories and 0666 for files but it depends on the umask value what the final permissions will be. By default the umask value is 0022 which creates files like 0644; it works like a subtraction.
So by resetting the umask to 0 you probably get what you need.
umask(0);
$zip = new ZipArchive;
if ($zip->open('upload/'. $username . $file_ext) === TRUE) {
$zip->extractTo('dir/' . $username);
$zip->close();
} else {
echo 'failed';
}
Related
I'm writing the code for converting disqus comments to HashOver system, and I have code like this:
// $threads is list of threads from disqus api that I cached on disk
foreach ($threads as $thread) {
$dir_name = getSafeThreadName(preg_replace("%^https?://[^/]+%", "", $thread['link']));
$dir = 'threads/' . $dir_name;
if (!is_dir($dir)) {
mkdir($dir);
chmod($dir, 0774);
}
// ...
// $thread_posts are $post that belong to $thread
foreach($thread_posts as $post) {
$xml = new SimpleXMLElement('<comment/>');
// ...
// $name_arr is array of numbers for HashOver comments
$fname = $dir . '/' . implode('-', $name_arr) . ".xml";
$f = fopen($fname, 'w');
fwrite($f, $xml->asXML());
fclose($f);
chmod($fname, 0664);
}
}
it created directory for each of my posts in threads that that is read/write with owner apache:apache and inside there are files like 1.xml with owner root:root
why root:root? How can I make it apache:apache?
EDIT:
This is no a duplicate, I don't want to change permission to apache:apache from root:root, which can be done using chown, but I want to make it so it don't change it to root:root in first place, I also want to know why it changed to root:root. This looks like a bug in php or apache for me or some wrong configuration in apache on my side. I don't think is the code since it just open, write and close file.
Don't know why and I would like to know, but this solve the issue:
I've use this:
chmod($dir, 0775);
instead of:
chmod($dir, 0774);
directory was not executable for others and it make files in that directory owned by root when created. Very weird.
When I upload photos to my web server I try to split up the photos into several folders so that I won't have so many photos in 1 single folder.
for example inside a class:
$filename = hash('crc32b', mt_rand());
$img_dir = UPLOAD_DIR.DS.'img'.DS.$filename[0].$filename[1].DS.$filename[2].$filename[3].DS.$filename[4].$filename[5];
DS is a short version of DIRECTORY_SEPARATOR
This could create directories like these:
public_html\assets\upload\img\25\55\8b
public_html\assets\upload\img\00\8c\2a
if file does not exist and there are no directories like that already
$img_path = $img_dir.DS.$filename.'.jpg';
if (!file_exists($img_path) && !is_dir($img_dir)) {
$mode = 0755;
mkdir($img_dir, $mode, true);
chmod(UPLOAD_DIR, $mode);
chmod(UPLOAD_DIR.DS.'img', $mode);
chmod(UPLOAD_DIR.DS.'img'.DS.$filename[0].$filename[1], $mode);
chmod(UPLOAD_DIR.DS.'img'.DS.$filename[0].$filename[1].DS.$filename[2].$filename[3], $mode);
chmod(UPLOAD_DIR.DS.'img'.DS.$filename[0].$filename[1].DS.$filename[2].$filename[3].DS.$filename[4].$filename[5], $mode);
}
I wan't all folders to be 755, how can do that recursively?
EDIT:
Also why do I get 493 as output when I do echo $mode; or echo 0755; ?
If you have access to the shell, and assuming the OS is Linux, I'd go with:
system('chmod -R ' . escapeshellarg(UPLOAD_DIR));
As for your edit, 0755 is an octal which in decimal is 493.
EDIT: you can also try this function, beware that $path should be the full path to a single file, or the path to a directory without trailing slash
function chmod_recursive($path, $mode) {
if(is_dir($path)) {
foreach(glob("$path/*") as $file) {
chmod_recursive($file, $mode);
}
}
else if(is_file($path)) {
chmod($path, $mode);
}
}
calling it like this:
chmod_recursive(UPLOAD_DIR, 0755);
Iterate over the directories starting at the root:
foreach (new DirectoryIterator(UPLOAD_DIR) as $fileInfo) {
if($fileInfo->isDot()) continue;
chmod($fileInfo->getFilename(), $mode);
}
taken from here
I'm trying to run a php script from the command line in vagrant, but I'm getting a permission denied error when trying to delete a file.
Using the command sudo chmod 777 messages/ does not work, because I can't change the directory permissions, vagrant's shared folders don't allow that.
I also tried to use chmod and umask to change the directory's and file's permissions to be able to delete it, but to no avail.
$oldUMask = umask(0000);
chmod($dir, 0777);
chmod($file, 0777);
unlink($file);
umask($oldUMask);
How can I fix this? Am I missing something obvious?
The directory structure is like so:
/vagrant
/app
/messages
And the owner and group of the directory is www-data, vagrant is run with those user and group settings aswell.
This is the complete script:
<?php
require 'cli-start.php';
use CodeRichard\Config\Config;
use CodeRichard\Text\MessageInfo;
use CodeRichard\Text\TextMessage;
$dir = 'messages/';
$iterator = new DirectoryIterator($dir);
$file = null;
/** #var SplFileInfo $entry */
foreach($iterator as $entry)
{
$ext = $entry->getExtension();
if($entry->isDir() || strtolower($ext) != 'json')
{
continue;
}
$file = $entry->getRealPath();
break;
}
if($file != null)
{
$message = json_decode(file_get_contents($file), true)['message'];
$service = new Services_Twilio(Config::get('twilio.account_sid'), Config::get('twilio.auth_token'));
$messageInfo = new MessageInfo(Config::get('twilio.from_number'), Config::get('twilio.to_number'), $message);
$textMessage = new TextMessage($service, $messageInfo);
$status = $textMessage->send();
if($status['sent'])
{
$oldUMask = umask(0000);
chmod($dir, 0777);
chmod($file, 0777);
unlink($file);
umask($oldUMask);
}
echo $status['message'];
}
The known problem. The simplest solution is to modify in the Vagrantfile the synced folders settings:
config.vm.synced_folder "./htdocs", "/var/www", owner: "vagrant", group: "www-data", mount_options: ["dmode=775,fmode=664"]
I am trying to delete a folder with files inside of it but the following code does delete the files, but not the folder.
$nameFolder = $_GET['delete'];
$dir = '../projecten/projecten/'.$nameFolder.'';
$filesIN = glob($dir."/"."*");
$status = 'false';
foreach($filesIN as $files) //here i take all the files
unlink($files);
$status = 'true';
if($status=='true'){
rmdir($dir);
$status = 'false';
}
[edited] Only empty directories can be deleted.
Try:
<?php
//recursively remove a directory
function rrmdir($dir) {
foreach(glob($dir . '/' . '*') as $file) {
if(is_dir($file)){
rrmdir($file);
}else{
unlink($file);
}
}
rmdir($dir);
}
//Example
$nameFolder = $_GET['delete'];
$dir = '../projecten/projecten/'.$nameFolder.'';
rrmdir($dir);
?>
source: http://www.php.net/manual/pt_BR/function.rmdir.php#108113
I would check the file permissions. On linux:
ls -al /path/to/projecten/projecten/
In simple terms the web server user must have write access to the directory in order to delete the file, for example the user www-data. In the below example the user lt can delete the test file:
drwxrwxr-x 2 lt lt 4096 Apr 29 08:54 test
Also I don't understand this bit of code:
$status = 'true';
if($status=='true'){
rmdir($dir);
$status = 'false';
}
Why not just have:
rmdir($dir);
As $status will always be 'true'.
You could also try using a system call, eg:
system `rm -rf /full/path/to/projecten/projecten/$nameFolder`;
Be very careful with that system command though - If you delete the wrong directory there is no going back!
A safer system command to use if you know the directory is empty would be:
system `rmdir /full/path/to/projecten/projecten/$nameFolder`;
But as pointed out in the comments above be very careful deleting a directory based on a $_GET variable. Imagine if the GET variables was '../../projecten' especially with the 'rm -rf' system command
Not an answer, but please change:
$nameFolder = $_GET['delete'];
To:
$nameFolder = basename($_GET['delete']);
And you may want to also add a:
if (is_dir('../projecten/projecten/'.$nameFolder) {
// ... do stuff here
} else {
// not a valid path
}
I have a Video folder on my server which has 755 permission. The problem is: when someone goes to upload video file, it can't be upload into that folder because of permission error.
If I change the permission to 777, then Video can be uploaded. But I don't want to allow the folder permission to 777 for security reason.
Is there any way in PHP to temporary change the permission to 777 while uploading video?
PHP provides a function, chmod() for the task.
Attempts to change the mode of the specified file to that given in mode.
You can put it in an if statement, and if it returns false, you can skip the upload file part.
The usage will be like
if( chmod($path, 0777) ) {
// more code
chmod($path, 0755);
}
else
echo "Couldn't do it.";
As described in the chmod function manual, the $mode must be in octal format - with leading zero, i.e chmod($path, 0777)
There is a way (PHP provides chmod function) but since PHP is not the owner of the folder, you won't be able to change the permission. And I think you are solving the wrong problem. Add webserver and PHP in the same group and give 775 to the folder.
You have to initialize the config for the upload, like this:
$config['remove_spaces'] = FALSE;
$config['upload_path'] = $path;
$this->upload->initialize($config);
$this->load->library('upload', $config);
You can use chmod() function.
For more information, try here
Warning: You cannot undo the file permissions that are changed by the script below. Proceed with extreme caution.
Important: this code should only be used if you remember to delete it immediately after use. As above, its use may put your site into an insecure state.
//replace dirname(__FILE__) with desired folder.
file_fix_directory(dirname(__FILE__));
function file_fix_directory($dir, $nomask = array('.', '..')) {
if (is_dir($dir)) {
// Try to make each directory world writable.
if (#chmod($dir, 0777)) {
echo "Made writable: " . $dir . "";
}
}
if (is_dir($dir) && $handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
if (!in_array($file, $nomask) && $file[0] != '.') {
if (is_dir("$dir/$file")) {
// Recurse into subdirectories
file_fix_directory("$dir/$file", $nomask);
}
else {
$filename = "$dir/$file";
// Try to make each file world writable.
if (#chmod($filename, 0666)) {
echo "Made writable: " . $filename . "";
}
}
}
}
closedir($handle);
}
}
or you can use terminal for this
chmod -R 755 public_html/test