I try to delete multiple images from folder and also from database, deleting from database is working fine, problem is with deleting from folder I'm using explode function because I have store multiple images inside one column in database. It just won't delete images from folder.
$query = "DELETE FROM table_gallery WHERE id = $deleteId";
$result = mysqli_query($con, $query);
while($row = mysqli_fetch_assoc($result)) {
$temp = explode(',',$row['images'] );
foreach($temp as $image){
$images[]="uploads/gallery/".trim( str_replace( array('[',']') ,"" ,$image ) );
}
foreach($images as $file) {
// Delete given images
unlink($images);
}
}
You have a few issues going on here,
1) Variable Confusion
The most notable is this:
foreach($images as $file) {
// Delete given images
unlink($images);
}
You are opening the array of $images and then dealing with each element in the array as a string reference ($file), but your unlink() command is calling the array, and you can't do that.
Unlink requires you to give it a filepath string. Not an array.
Fix:
foreach($images as $file) {
// Delete given images
unlink($file);
}
Better:
As an aside, if unlink($file); does not work, then you should check your filepath is correct. Remember the current PHP working directory is the directory the PHP script is in, so you should probably set your deleted image path to being the full server filepath such as:
unlink($_SERVER['DOCUMENT_ROOT']. $file);
To ensure you're certain of the file you're deleting.
foreach($images as $file) {
// Delete given images
// /serverfolder/accountfolder/public_html/uploads/gallery/imagename.jpg
unlink($_SERVER['DOCUMENT_ROOT'].$file);
}
2) Your Safety and Security:
Your variable $deleteId might be safe, but it might not. We can't tell from the code you show but you should be aware that if the $deleteId variable is, for example;
$deleteId = '1 OR id > 1';
// which generates:
$query = "DELETE FROM table_gallery WHERE id = 1 OR id > 1";
This is a security risk for your SQL and will delete all records on your database table (and folder). You should use Prepared Statements to ensure this doesn't ever happen.
3) Logic Confusion
you have a reference call mysqli_fetch_assoc but the DELETE SQL command will not return a result set, instead if it is successful it will simply return true.
Returns false on failure. For successful queries which produce a result set, such as SELECT, SHOW, DESCRIBE or EXPLAIN, mysqli_query() will return a mysqli_result object. For other successful queries, mysqli_query() will return true.
You need to structure your code somewhat differently, loading the images column value BEFORE you delete the row.
So, to restructure your code:
Check variables are safe.
load images column values
cycle through values and delete
Once deletion is confirmed then DELETE SQL.
For example:
$query = "SELECT images FROM table_gallery WHERE id = ".(int)$deleteId;
$result = mysqli_query($con, $query);
$abort = false;
while($row = mysqli_fetch_assoc($result)) {
$temp = explode(',',$row['images'] );
foreach($temp as $image){
$images[]="uploads/gallery/".trim( str_replace( array('[',']') ,"" ,$image ) );
}
foreach($images as $file) {
// Delete given images
if(!unlink($_SERVER['DOCUMENT_ROOT'].$file)){
// Delete failed so abort
$abort = true;
}
}
//
if(!$abort){
// all correct images on disk deleted ok so delete DB row
if(mysqli_query($con, "DELETE FROM table_gallery WHERE id = ".(int)$deleteId)){
// Yay deleted ok!
}
}
}
Closing thought:
You need to learn to read your PHP error logs which will spell out all the above.
Related
I have a bunch of extra garbage uploads in a directory from when I was testing my app. The files I want to keep are in a table in my database. I want to delete a file in the directory if it's not in the table. Here is my attempt
<?php
$query = 'SELECT file_name FROM DummyFile';
$statement = $db->prepare($query);
$statement->execute();
$files_in_use = $statement->fetchAll();
$statement->closeCursor();
$path = getcwd();
$all_files_in_directory = scandir($path);
$all_files_in_directory = array_diff($all_files_in_directory, array('.', '..'));
foreach($all_files_in_directory as $file) {
if (!in_array($file, $files_in_use)) {
unlink($file);
}
}
?>
However this code deletes every single file in the directory regardless. Which means my conditional in the loop is evaluating to true every time when it shouldn't be. Please help
You're assuming $files_in_use is an array of filenames. It's not; it's an array of database rows, each being an array itself.
To get just the filenames you need:
$files_in_use = array_column($statement->fetchAll(), 'file_name');
The rest of your code should then work.
I have this function, and this deletes textfiles after a certain age from my database automatically.
$r = new textfiles;
$db = new DB;
$currTime_ori = $db->queryOneRow("SELECT NOW() as now");
...
if($this->site->textfilesretentiondays != 0)
{
echo "PostPrc : Deleting textfiles older than ".$this->site->textfilesretentiondays." days\n";
$result = $db->query(sprintf("select ID from textfiles where postdate < %s - interval %d day", $db->escapeString($currTime_ori["now"]), $this->site->textfilesretentiondays));
foreach ($result as $row)
$r->delete($row["ID"]);
}
Now I would edit this function so that at first all textfiles are automatically downloaded in a root directory /www/backup and then the script should delete the textfiles with the string $r->delete($row["ID"]);
At the moment I have no idea how I could implement this.
For me it's seems to be impossible to give you an completely answer to your question because leak of informations.
Do you store the whole file-content in database or only the path and filename?
It would help us to see whats the content of "$row" which represents one row from database.
If you just store the filename (and optionally the path) you could use the "copy" (http://php.net/manual/de/function.copy.php) function from php to copy the file to your backup-directory. Please note, you have to ensure that the user who's executing the script or running the web-server have the privileges to write into the directory.
You could add this functionality to class textfiles as as method like makeBackup.
There are few information, but I'll give it a try. If you want to backup the rows before deleting them, you can store them in .txt file in json_encoded form using this piece of code inserted in the FOREACH loop, before delete command:
$myfile = fopen("/www/backup/".$row["ID"].".txt", "w") or die("Unable to open file!");
$txt = json_encode($row);
fwrite($myfile, $txt);
fclose($myfile);
By your approach ..
function delete ($id){
$result = $db->query(sprintf("select * from textfiles where id=$id);
//if you have filepath use copy as SebTM suggested
$path = $row['path']; //assuming path is the column name in ur db
$filename = basename($path); //to get filename
$backup_location = '/www/backup/'.$filename;
copy($path, $backup_location);
//if you have data in db
$content = $row['data'] //assuming data to be backed up to file is in a field 'data'
$backup_location = '/www/backup/file.txt';
file_put_contents($backup_location, $content);
}
But this is not the most optimal approach , you could shift even the initial query into delete function above , and call delete function only once, instead of calling it in a loop ..
i want write a code in php that
go to dir "upload" and see if is a file that dont Exists in my db
and remove this file if it find.
$like = scandir(upload);
$myFile1 = upload;
$myFile1 .= '/';
$myFile1 .= $like;
$rs = mysql_query('SELECT url from blog');
while(list($url) = mysql_fetch_row($rs))
{
if($like != $url){
unlink($myFile1);
}
}
its write me a eror
Warning: unlink(upload/Array) [function.unlink]:
scandir returns an array of files; you'll need to step through that array, to check each one individually:
$like = scandir('upload');
foreach ($like as $thisFile) {
$rs = mysql_query("SELECT url FROM blog WHERE url='$thisFile'");
if (! mysql_num_rows($rs)) {
if($thisFile != "." and $thisFile != ".."){
unlink ('upload/' . $thisFile);
}
}
}
You're checking each file in that directory to see if it has an entry in the blog table; if it doesn't, it's passed to unlink. I've not tested this code, but it should give you an idea about how it runs.
A couple of notes:
What if there are directories in the directory? You should add some checking to skip over them. Don't forget that you'll have ./ and ../ in there.
What if there's an entry in the blog of ..\..\..\..\etc\passwd? You should add some checking to make sure that $thisFile isn't something you don't want to delete.
This is using mysql; that's deprecated, and you should look at migrating to mysqli or PDO for the query. You can also then convert the query into a prepared statement, which will help it run more efficiently.
I have been trying different things in order to get this script to query the MySql DB for the image name and then go to the directory and return the image with the same name. It seems simple in concept, but I keep getting a bunch of mixed results and none of the results return the image.
Here is the most recent code that I tried:
$sqlCar = mysql_query("SELECT img_nm FROM vehicles WHERE sold='n' ORDER BY year DESC");
/***************************
****
Code Returns '1'
******************************/
$dbImage = $sqlCar;
$dirImage = scandir($_SERVER['DOCUMENT_ROOT'].'/car-pics/');
function imgCompare($dbImage){
if ($dbImage == $dirImage[img_nm]){
echo $dirImage[img_nm];
} else {
echo "Image Coming Soon";
}
}
You're not adding $dirImage as a parameter to the function. You can solve this by adding it as a parameter, or adding the global keyword to the first line of your function like this:
function imgCompare($dbImage){
global $dirImage;
if ($dbImage == $dirImage[img_nm]){
echo $dirImage[img_nm];
} else {
echo "Image Coming Soon";
}
}
Also, what values are in img_nm in the database? scandir uses an array of index values. So $dirImage[0] would work, but $dirImage['filename.jpg'] would not.
The mysql_query function is not going to return the value you are looking for directly into $sqlCar where it is directly accessible.
you will have to do something like
$row = mysql_fetch_array( $sqlCar );
And then reference the array to get the image name
$dbImage = $row['img_nm'];
This is the code
$query = mysql_query("SELECT avatar FROM users WHERE UserID = ".$userID."");
$row = mysql_fetch_array($query);
$user_avatar = trim($row['avatar']);
unlink($user_avatar);
but for some reason i get this error Warning:unlink();
why $user_avatar returns empty ? and if i echo it shows t_cabbbccebbfhdb.jpg
unlink remove files whereas unset is for variables.
If the variable returns empty, perhaps the query does not return any records. Did you try to run the query manually?
$query = mysql_query("SELECT avatar FROM users WHERE UserID = ".$userID."");
$row = mysql_fetch_array($query);
$user_avatar = trim($row['avatar']);
unset($user_avatar);
//if you want to unlink file then
if(!empty($user_avatar)) {
unlink($home.$user_avatar); // $yourFile should have full path to your file
}
In PHP unlink is used to delete a file, make sure you are giving right path. see here for details http://se.php.net/unlink
try unset for variables. http://se.php.net/manual/en/function.unset.php