Why would file_put_contents() succeed but touch() fail? - php

I'm running a script that makes some changes to the contents of a file then resets its modification time to what it was before. Intermittently, I'll find the following errors in my log:
touch() [function.touch]: Utime
failed: Operation not permitted
This on the line immediately after a file_put_contents() call appears to have changed the contents of the file I tried to touch(). There are no errors associated with the file_put_contents() line.
Has anyone had this happen? Can anyone figure out what set of permissions would allow me to write a file but not change its modification time? I'm doing this on Linux.

This is a bug with PHP's touch command. Even if you have write permission to the file, it fails if PHP isn't also the "owner".
If you're using Apache and Linux, use this command on your server's console to make PHP the file's owner:
sudo chown www-data:www-data /YourPATH/YourFILE
Better still, update the entire folder containing files you want PHP to control:
sudo chown -R www-data:www-data /YourPATH/YourFOLDER
Side Note: Because PHP can write to the file, that means it must have user or group write permission. Since that's the case, touch should not behave this way. It seems like a bug.

It could be possible that the file gets created with wrong permissions. Try to chmod 777 the file just after the file_put_contents and then touch the file.

As rossoft says, PHP is probably not the owner of the file. But setting the permissions to 777 might not be the best solution. I'd preferr:
function touch_file($file) {
fclose(fopen($file, 'a'));
}
touch_file('/path/to/file');

Only recently, I've had a similar problem and I think I know the answer.
The actual purpose of touch() is to update the modification and access times of a file. Creating the file is just a side-effect.
If you're using Linux, but writing to an NTFS partition as you might with a dual-boot configuration, depending on how the partition is mounted, touch() might have problems changing the access time on files. The file will be created, but touch() will still fail because the underlying system returns an error status. The same thing can be observed from the command line where you'll get a "permission denied" message.
There doesn't seem to be any documentation regarding this in the man pages for mount, ntfs-3g, or touch (Linux command), but the problem is mentioned in the comments on the touch() PHP function page.
Tweaking mount options might provide a solution, but you're better off using is_writable() to check permissions and fopen() to create files.

Related

touch(): Utime failed: Operation not permitted

I tried to run this command:
php -r "touch('/mnt/my_drive/test.txt', 1600981328);"
I got this error:
PHP Warning: touch(): Utime failed: Operation not permitted in Command line code on line 1
If I run it with sudo, I don't get the error.
/mnt/my_drive is an NTFS drive. The mount was created in fsab with umask=000, so I have no idea, why do I get permission error.
Please do not mark this as a duplicate, because the similar questions have these answers:
Check the permissions: It should be right because of umask=000
Run composer/php in elevated mode: I would like to avoid running the webserver as admin
Modify some library files in vendor: I get this error even in command line, as my example shows
Don't use ntfs: It is not my choice
This may happen when the user PHP runs as isn't the owner of the cache files. Checkout this link Utime failed: Operation not permitted
Your code worked perfectly on my machine with php7.4 and ntfs mounted with:
/dev/sdaX on /mnt/tmp type fuseblk rw,relatime,user_id=0,group_id=0,allow_other,blksize=4096)
Are you sure the directory you are trying to do this in allows you to create files? Does the directory exist?
If you can create normal files without setting the time parameter it might have something to do with ntfs or fuse mounting it.
In this case:
Try to run the php command in strace to see what actually fails, that should help nail down the error.
EDIT: Also the umask should not matter in this case, what matter are the permissions of the directories that contain the file.
Updating file modification time fails unless issued by the owner. Try to clear the cache files and recreate them with the PHP user as the owner.
It is never assumed a good point to change modification times, unless there is a need to file something in with others. It's hasty and shows no function to it. The only thing i can tell you is that you have to own the file, you may need root, just to access these permissions and that with sudo you can do anything. So you've no hope of this. I hope that can bring you to believe in some other way of a file system breakdown for your clients.

Deleting video files using unlink() in PHP 7

I'm facing a problem with deleting video files from folder using php unlink() function , image are deleting but when trying deleting videos it says
unlink(file_path) : permission denied.
You (running your script as either through CLI or a webserver) need write access to the directory in which the files are located. so access to the file is not enough.
Your image directory would be different and writable for webserver or cli.
chmod("your/video/dir/path",0777);
try using above code before unlink the video in your script.
Edit: Looks like you are using Windows. Unfortunately, my answer is for Unix-like operating systems (so Linux, MacOS). You could try installing Bash extension for Win8+, but still I'm not sure if this would work. However, I'm keeping my answer in case of anyone with similar problem is looking here for an answer.
Changing permissions through PHP might work in some cases, but not always, because if you don't have permissions to delete the file you might also not have permissions to change them.
The best solution is to create a directory where you will keep files to which PHP will have full access. Let's call it dirname. Once you have created a directory, change its owner and group to the one corresponding to your web server user's name (if you're using Apache, it's "www-data"), for example: chown www-data:www-data dirname.
Once you've done that, change folder's permissions. My suggestion is 744, it will assure that user who owns it will have all permissions, and everyone else will be able only to read it. To do that, execute the following command: chmod -R 777 dirname.
Now you should be able to do anything you want with the files in given directory directly from PHP.

Ruined all permissions in ubuntu

Accidentally i rewrote all folders permission from root.
chown -R www-data:www-data /​
Just for example. Luckily i have another server. So i started fix all permissions manually one by one. And now everything seems work fine except for one thing: php can't write files.
I have a suggestion that some php or apache process have wrong permissions.
So symptoms:
The stream or file "/var/www/vhosts/.../httpdocs/storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied
Yes. I'm sure that files have correct permissions. Because this recursive process was not so fast to override /var folder too. At least some domain still untouched. So i checked it out.
Maybe it would be helpful to know that i use plesk. Because some .sock files could be located there.
I have no idea what i did but it works now. I hope one day it could be useful for someone too.
Just run script if you use plesk
/usr/lib/plesk-9.0/install_suexec
So in the we could say i just reinstall script.

How to write a file with PHP in Linux?

I want to write text file using PHP.
I can write it using fopen and fwrite function on Windows platform. But, that program is not able to write it on Linux Platform.
Is there any solution?
fopen and fwrite work exactly the same on Linux, but you may have a permission issue there. To solve this, you need to check:
the user under which PHP runs (in a vanilla Apache/PHP install, this is usually www-data)
the permissions and ownership of the directory you are trying to write to
What you need is write permission on the directory for the PHP/Apache user. The easiest (and dirtiest) way of achieving this is is to just make the directory world-writable (chmod o+w the_dir), but this is highly insecure, allowing anyone with any kind of access to the system to store stuff there. A better solution is to either make the PHP user the owner of the directory and specify permission 700 (or 755 if you want it to be world-readable), or create a new group, put the PHP user and yourself in that group, set the group on the directory, and set permission 770 (775 for world-readability) on the directory.
It should work, please check the users permission to the directory and/or file.
You always can try this program writing to /tmp/my.log, it should work)
Of course, you can use the same fopen and fwrite functions on Linux.
The only special thing is that the folder where it's written (or at least the file itself) must be given write permissions.
An easy way to test it would be to set the file permission (or its folder) to 777.
fopen and fwrite works on both SO.
Probabily you have permission denied. Try to give write perms on your file on linux.
You can use php chmod func

Can I use php's fwrite with 644 file permissions?

I am trying to set up automated .htaccess updating. This clearly needs to be as secure as possible, however right now the best I can do file permission-wise is 666.
What can I do to setup either my server or php code so that my script's fwrite() command will work with 644 or better? For instance is there a way to set my script(s) to run as owner?
EDIT:
I realized I actually just had a permissions issue, you should be able to use fwrite no problem with 644 permissions. See my answer below.
The apache process should always run as apache:apache - if you must enable write permissions in executable (i.e. DocumentRoot) directories, create a group, add apache and set group write permissions (so 664).
It's best to have .htaccess updated by a cron script reading config data from a database, as giving apache write permissions to executable directories is frowned upon in case a vulnerability in your code allows a malicious user to write new files to those directories.
You can't change the process's owner. If you're on a shared server, see if they have suPHP as an option.
These suggestions were great, however I ultimately realized that the answer to my question is YES - and you shouldn't have to do anything at all... as long as the Owner user of the file/directory you are trying to write to is the same user the script is running as. My mistake was that I accidentally had my file ownership out of whack therefore needed higher permissions 666 and 777 in order to write to my files. Which makes sense because Wordpress can write to .htaccess with standard permissions.
Now I have things setup where a file running as user1 is writing to a file owned by user1:user1, and no problems whatsoever. Directories set to 755, .htaccess file set to 644.

Categories