check directory for files not in mysql database - php

I have this code which checks if there are any filenames in my database table "files" which are not in the directory "video/test". I have been trying to edit this code so that it does the opposite i.e it checks if there are any filenames in the directory "video/test" which are not in the database table "files". I am having some trouble switching the content to the other side of the clause. I'm getting mysql syntax errors. Can anyone help me out with this
$filenames = scandir("video/test");
$sql = sprintf( 'SELECT * FROM files WHERE filename not in ("%s")', implode( '","', $filenames ) );

Something like this:
$filenames = scandir("video/test");
$files = implode(",", $filenames );
$sql = sprintf( "SELECT * FROM files WHERE filename not in (".$files.")" );
Give it a try ;)
Saludos.

Related

Delete images from folder using php

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.

Delete file if it's not in an array

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.

Display INFORMATION_SCHEMA.COLUMNS results in a string

First of all, english is not my first language so sorry if I make some mistakes. I am kinda new to PHP and MySQL and I am working on a little personal project. I am stuck on something that I really don't know how to do and I would like to have your opinions on the best way to do it.
I want to generate a file (using fwrite) that will contain this information :
class applications
{
private $_"value1";
private $_"value2";
private $_"value3";
etc depending on how many columns the table have
}
"value" are equal to the name of each columns of a table.
To get the columns names I am using INFORMATION_SCHEMA.COLUMNS in this request :
$columns = $db->prepare("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '$_POST[dropdown]' AND table_schema = 'tp2'");
$columns->execute();
$resultCol = $columns->fetchAll();
To write the file I am using this code :
$ouv = fopen($dir."/".$nomfile.".class.".$ext, 'w+');
fwrite($ouv, $text);
The variable $text must contain the result of a foreach loop that looks something like that :
foreach($resultCol as $value3)
{
print_r("private "."$"."_".$value3[0].";"."<br/>") ;
}
This print_r would work if I would like to display it in a php page but I need to save it as a string in a file.
Since $text is a variable, I can't use a foreach in it and I really don't know how to do it.
So in your opinion, what would be the best/easiest way to do what I am trying to do ?
Steps:
Open file
Loop through the result set
read row column values
construct text
write into file
close the file
Example:
$ouv = fopen( $dir . "/" . $nomfile . ".class." . $ext, 'w+' );
foreach( $resultCol as $value3 )
{
$text = "private $_" . $value3[0] . ";" ;
fwrite( $ouv, $text );
}
fclose( $ouv );

how to delete files that not Exists show in db

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.

Automatically build mySql table upon CSV upload

Automatically build mySql table upon a CSV file upload.
I have a admin section where admin can upload CSV files with different column count and different column name.
which it should then build a mySql table in the db which will read the first line and create the columns and then import the data accordingly.
I am aware of a similar issue, but this is different because of the following specs.
The name of the Table should be the name of the file (minus the extension [.csv])
each csv file can be diffrent
Should build a table with number of columns and names from the CSV file
add the the data from the second line and on
Here is a design sketch
Maybe there are known frameworks that makes this easy.
Thanks.
$file = 'filename.csv';
$table = 'table_name';
// get structure from csv and insert db
ini_set('auto_detect_line_endings',TRUE);
$handle = fopen($file,'r');
// first row, structure
if ( ($data = fgetcsv($handle) ) === FALSE ) {
echo "Cannot read from csv $file";die();
}
$fields = array();
$field_count = 0;
for($i=0;$i<count($data); $i++) {
$f = strtolower(trim($data[$i]));
if ($f) {
// normalize the field name, strip to 20 chars if too long
$f = substr(preg_replace ('/[^0-9a-z]/', '_', $f), 0, 20);
$field_count++;
$fields[] = $f.' VARCHAR(50)';
}
}
$sql = "CREATE TABLE $table (" . implode(', ', $fields) . ')';
echo $sql . "<br /><br />";
// $db->query($sql);
while ( ($data = fgetcsv($handle) ) !== FALSE ) {
$fields = array();
for($i=0;$i<$field_count; $i++) {
$fields[] = '\''.addslashes($data[$i]).'\'';
}
$sql = "Insert into $table values(" . implode(', ', $fields) . ')';
echo $sql;
// $db->query($sql);
}
fclose($handle);
ini_set('auto_detect_line_endings',FALSE);
Maybe this function will help you.
fgetcsv
(PHP 4, PHP 5)
fgetcsv — Gets line from file pointer
and parse for CSV fields
http://php.net/manual/en/function.fgetcsv.php
http://bytes.com/topic/mysql/answers/746696-create-mysql-table-field-headings-line-csv-file has a good example of how to do this.
The second example should put you on the right track, there isn't some automatic way to do it so your going to need to do a lil programming but it shouldn't be too hard once you implement that code as a starting point.
Building a table is a query like any other and theoretically you could get the names of your columns from the first row of a csv file.
However, there are some practical problems:
How would you know what data type a certain column is?
How would you know what the indexes are?
How would you get data out of the table / how would you know what column represents what?
As you can´t relate your new table to anything else, you are kind of defeating the purpose of a relational database so you might as well just keep and use the csv file.
What you are describing sounds like an ETL tool. Perhaps Google for MySQL ETL tools...You are going to have to decide what OS and style you want.
Or just write your own...

Categories