Delete files which are not in a mySQL TABLE
The link above is to a Stack Overflow question with an answer that is (I believe) pretty close to what I'm looking for. I'm actually just seeking further clarification on the answer given.
The Question
I'm trying to delete files (picture files) in a folder only if they're
not present in a specific database table.
Just like a check of filenames and if they're present in the table
it's ok but if not delete them.
Any ideas how to do that?
The accepted answer
$result = mysql_query("SELECT filename FROM no_delete");
while($row = mysql_fetch_assoc($result)) {
$do_not_delete[] = $row['filename']; }
foreach(glob("*") as $filename) {
if (!in_array($filename, $do_not_delete)) {
//delete them
}
}
I'm not too savvy with PHP, but I don't believe they are specifying a folder path on the server here, are they? I'd like to be able to look inside a specific folder and check whether any images in that folder are within any database tables. If not, delete that image.
Before calling glob("*") just add a line chdir(""). Then you can search whichever directory you want to look at. I just went one level higher in the call below. You may specify whichever directory you want. Before doing a delete, just add an echo statement to $filename to verify if the correct files are being deleted.
chdir("../");
foreach(glob("*") as $filename) {
if (!in_array($filename, $do_not_delete)) {
//delete them
}
As described in this answer the first parameter, i.e. pattern, can contain the path to a directory relative to the current working directory of the script (which can be changed with chdir()) or an absolute path.
Consider this example from this tutorial page:
$dir = "/etc/php5/*";
// Open a known directory, and proceed to read its contents
foreach(glob($dir) as $file)
{
echo "filename: $file : filetype: " . filetype($file) . "<br />";
}
Related
I came up with this questioin. My background is from the Node.js. I am not usually quite used to be in PHP. That's why I'm aksing this question to solve the current issues.
The issues is that's to says I have certain Files and Folders that contains with a specific letters and number at the beginning. As you can see given by down below with a scrrenshot.
I just learn and writing some php code that I grabbed it from the internet resources. Take a look at what's my code:
I want this to detele this all folders which contains letters "exp_" and all the files names start with this numbers "xx-xx-xx" etc.
I created delete.php. When I'd called this file via the browser, I want to achieve to delete all the files and folder which for the No. 1 case.
All these folders and files are generated in everdays. That's why I do want to clean all those data.
<?php
$path = "test";
if(!unlink($path)){
echo "File has not deleted yet.";
} else {
echo "Successfully deleted!";
}
?>
Is there any how any solution to solve this issues? I will appreciate all in advanced who are giving me idea and suggestions from you guys.
You can do something like this:
$files = new DirectoryIterator(__DIR__);
foreach ($files as $file) {
if ( ($file->isDir() and strpos($file->getFilename(),'exp_')!==false) || ($file->isFile() and $file->getFilename() == date('d-m-Y') ) ) {
unlink($file->getPathname());
}
}
Thus, all folders with names like exp_ and files with today's date will be deleted.
I need to get a file based on the second half of the filename with PHP
The structure of the filename will always be NAME_123456789.dat where the number is a tracking_id(unique).
The name being John, Mel, Bronson, etc. And the number being a tracking_id.
What the process will be just for comprehension is that a person will enter their tracking_id. it will extract that from the search bar and plant it in the ftp search in the specific directory. Because the tracking_id is unique it should only return one result, hence ftp_get() right?
Any help is greatly appreciated.
Given the relatively small directory size (100+ from comments above), you should be ok first using ftp_nlist() to list all the files and then searching for and downloading the file you want.
$search = '_' . $trackingId . '.dat';
$searchLen = strlen($search);
$dir = '.'; // example directory
$files = ftp_nlist($connection, $dir);
foreach ($files as $file) {
// check if $file ends with $search
if (strrpos($file, $search) === strlen($file) - $searchLen) {
// found it, download it
ftp_get($connection, 'some/local/file/path', $dir . '/' . $file);
}
}
Better and more future-proof options can be found in Michael Berkowski's comment above...
How many files do you expect to be operating in the directory at any given time? If it is a small number, listing the contents via ftp may work suitably. If it is many thousands of files, you might want to store some sort of text manifest file to read from, or index them in a database.
These do hinge on how and when the files are uploaded to the FTP server though so given we don't know anything about that, I cannot provide any solutions.
I tried to create a folder to store all my images but it will not upload on its specific upload folder inside my installed theme.
Here is my code:
if(isset($_FILES['file']['tmp_name']))
{
$num_files = count($_FILES['file']['tmp_name']);//count file upload
for($i=0; $i<$num_files; $i++)
{
if(!is_uploaded_file($_FILES['file']['tmp_name'][$i]))
{
echo "no file upload!!";
}else
{
if(#copy($_FILES['file']['tmp_name'][$i], "/upload/".$_FILES['file']['name'][$i]))
{
$path = "upload/".$_FILES['file']['name'][$i];
//$sql = "insert into tblImage value ('".$path."')";
}else
{
echo "cant upload";
}
}
}
}
It's difficult to figure out exactly what went wrong because I don't know your setup, but try these things:
It's inadvisable to use #copy in this case, especially while you're trying to figure out what's going wrong. Copy will return false on failures and show other error messages in exceptional situations, unless you prefix it with #. If your disk is full, for example, it'll fail silently. Just copy is likely more useful for this.
Your file naming is, at the very least, difficult to decipher. Specifically, what paths are you using? PHP file operations like copy require precise path information. Your path, /upload/, which is upload/ later, refers to something relative from some arbitrary place, that may change. To solve this, figure out a good absolute path. If you're uploading to WP uploads, start with wp_upload_dir and build from there.
Unless you absolutely need a copy of the file from the original location later, move it instead of copying it. Remember that you'd be moving it to the uploads folder, so it'd still be available later, just somewhere else. This also avails you to move_uploaded_file().
There are some great comments (like from #kabiir) about how to debug what you've got. It's hard to figure out exactly what's going wrong without some debugging information.
Try:
if(isset($_FILES['file']['tmp_name'])) {
for ($i = 0; $i < count($_FILES['file']['tmp_name']); $i++) {
$file = $_FILE['file']['tmp_name'][$i];
error_log('source: ' . $file);
if (is_uploaded_file($file) && isset($_FILE['file']['name'][$i])) {
$name = $_FILE['file']['name'][$i];
error_log('uploaded name: ' . $name);
$destination = trailingslashit(wp_upload_dir()) . $name;
error_log('destination: ' . $destination);
if (!move_uploaded_file($source, $destination)) {
echo 'failed to move file.';
continue;
}
// Now $destination contains where the file was moved to.
}
}
}
This code will output to your log (or wherever else you have error logging pointed to) the source file+path, the uploaded file name and destination file+path, per file.
Unless there's something very special you're doing, wp_handle_upload() should take care of all your needs without rewriting this. When it's done, it calls the wp_handle_upload filter. Hook to the end of that filter's chain to do your SQL or whatever else. There are also many plugins that do what you're trying to do and save you from having to code it yourself.
As a side note, you ought not create SQL entirely by hand in WP. Use the wpdb class, with the $wpdb->prepare() function. This also allows you to use $wpdb->prefix, which is the prefix for your table. (You've prefixed your table and created it according to WP standards, right?)
I'm making a simple file listing function in PHP, just to recursively list all the files in a directory.
The function I have right now looks something like this:
<?php
function listFiles($dir){
echo "<ul class=\"filebrowser\">";
$dirCont = scandir($dir); // scan the whole directory
sortFoldersFirst($dirCont,$dir); // sort alphabetically, folders first
foreach ($dirCont as $value) {
if (!in_array($value,array(".","..",".deleted"))){ // don't list the parent folder, current folder, or the (hidden) .deleted folder
if (is_dir($dir . DIRECTORY_SEPARATOR . $value)){ // if it's a folder
echo "<h3 class=\"filebrowser\">" . $value . "</h3>"; // show the folder name
listFiles($dir . DIRECTORY_SEPARATOR . $value); // do the same again for the child folder
} else {
echo "<li>".$value."</li>"; // a link to the file
}
}
}
echo "</ul>";
}
?>
This gives me something like this:
This technique works just fine, however, I'd like to store a little more information about the files, like the author, comments, maybe a link to a thumbnail etc.
I'd like to get rid of the 'real' directory structure, and store everything in a database. (Just all files in 1 big folder, and links to the files in the database, not the actual files)
How can I store this information in the database, and how can I get it back out, without changing the result in the browser.
In other words: how can I get the tree structure in and out of the database, and how do I recursively loop through it.
I found this answer.
It shows how to make a database tree structure by saving the parent folder's id for every file/folder. This makes it easy to get the full path of a file, but it seems a bit less convenient to list all contents of a folder.
Is there a better solution to this problem?
Thanks in advance,
Pieter
I'm currently building a very low level CMS for friend's artist web page that will allow her to upload, edit, and delete images along with designating categories for them and posting news posts about shows and so on.
I'm sure there is a very easy solution to this problem of mine but my inexperience in programming has me left at a loss; so here goes.
The Problem
The problem occurs on a page where the user can delete an image that has been uploaded. Here is the snippet of code where the problem occurs:
// Assign selection to variables in memory...
$img_id = $data["img_name"];
// First, collect the file path to the image being deleted...
$rs = mysql_query("SELECT img_path FROM img_uploads WHERE img_id = '$img_id'") or die(mysql_error());
list($img_path) = mysql_fetch_row($rs);
// Then delete that row from the DB...
mysql_query("DELETE FROM img_uploads WHERE img_id = '$img_id'") or die(mysql_error());
// Now, using the file path collected earlier, delete that file from the server.
unlink($img_path);
// Quickly make sure that the file has been deleted by checking if it exists... if it still exists return error.
if(file_exists($filename)) {
$err[] = "ERROR - There was an error deleting the file! Please try again.";
$_SESSION["errors"] = $err;
header("Location: img_del.php?doDel=failed");
exit();
}
// Scan the directory now that a file has been deleted to see if the dir is empty. If so, delete it. (No use in having empty folders!)
$file_types = array("gif","jpg","png"); // file types to scan for...
$path_parts = pathinfo($img_path); // get the directory from the file path...
$dir = $path_parts["dirname"] . "/"; // assign it to a new variable...
$handle = opendir($dir);
$scan = scandir($dir); // now, scan that directory...
$image_found = FALSE;
for($i=0; $i<count($scan); $i++) {
if ($scan[$i] != '.' && $scan[$i] != '..' && in_array(end(explode('.', $scan[$i])), $file_types)) {
$image_found = TRUE;
}
}
closedir($handle);
if(!$image_found) {
rmdir($dir);
}
I first delete the DB row containing image info, then delete the file from the server. this works fine, however, I also want to check if the directory is left empty after deleting that file. I check if the directory is empty using a loop and if no file is found, I run mkdir(). For some reason it keeps returning an error saying that the directory is not empty
I've searched the web and this site for a solution but I've yet to find one. I'm sure it's out there but I'm having trouble finding it which why I came here. What should I do?
Thanks in advance for any help submitted!
NOTE
I have also checked for hidden files and folders but no luck...
Here is a link to an image that pretty much sums up my problem in a nutshell
Are you sure PHP has permission to delete the file? Since you say you've checked for hidden files, this seems to be the only remaining option. CHMOD 0777 when in doubt (I'd never recommend this usually, but if you're deleting it anyway...), and make sure the folder has the proper owner to let php delete it.