Hi, I created a script which I use to clean my database from missing entries. With it I both check if a file on the server is missing a database entry and if a database entry exist with no corresponding file on the server. The user first submits a form where he chooses if what exactly he wants to clean and if files with no corresponding database entry should be deleted or registered in the database.

The error I receive is:
Warning: in_array() expects parameter 2 to be array, null given in C:\xampp\htdocs\storage\php\file_upload\clean_database.php on line 59

...or line 48 if the user chooses to delete the files instead of registering them.

This is the script for the database cleaning:

<?php
require "../database/config.php";
require "../database/connect.php";
ini_set('display_errors', 1);
error_reporting(E_ALL);

$redirect = "http://".$_SERVER['HTTP_HOST']."/storage/"; //Where the browser shall be redirected to after execution
$myDirectory = $_SERVER['DOCUMENT_ROOT'].'/storage/uploaded_files/'; //Directory that should be cleaned
$httpDirectory = "http://".$_SERVER['HTTP_HOST']."/storage/uploaded_files/"; //Same directory but as url
//Settings for the clean up from the user
$option_cleanOrDelete = $_POST['submit'];
$option_entryMissing = $_POST['database_entry_missing'];

//Getting all the files from the directory into an array
$openDirectory = opendir($myDirectory);
while($entryName = readdir($openDirectory)){
	$dirArray[] = $entryName;
	#Making sure that no hidden files gets included if that option is choosed
	if (!isset($_POST['clean_hidden'])){
		if(substr(end($dirArray), 0, 1) == "."){
			array_pop($dirArray);
		}
	}
}
closedir($openDirectory);

//Fetching database contents
$result = mysql_query("SELECT * FROM files");
$fileName_database = mysql_fetch_array($result);

//Checks if the user wants to delete the data or clean it
if ($option_cleanOrDelete == 'Clean'){
	#checks if the user wants the database cleaned
	if (isset($_POST['clean_database'])){
		while($fileName_database = mysql_fetch_array($result)){
			if (!in_array($fileName_database['filename'],$dirArray)){
				mysql_query("DELETE FROM files WHERE filename='$fileName_database[filename]'") or die("Error :".mysql_error());
			}
		}
	}
	
	//File cleaning
	#Checks if the files should be cleaned
	if (isset($_POST['clean_files']) && !empty($dirArray)){
		#If the user wants to delete files missing database entries
		if ($option_entryMissing == "delete"){
			for ($i = 0; $i < count($dirArray); $i++){
				if (!in_array($dirArray[$i],$fileName_database['filename'])){
					$fileName = $myDirectory.$dirArray[$i];
					if (!unlink($fileName)){
						echo ("Error deleting $fileName");
					}
				}
			}
		}
		#if the user wants to register missing database entries
		else {
			for ($i = 0; $i < count($dirArray); $i++){
				if (!in_array($dirArray[$i],$fileName_database['filename'])){				
					$permission = "1";
					if (substr($dirArray[$i], 0, 1) == "."){
						$hiddenFile = "yes";
					}
					else {
						$hiddenFile = "no";
					}
					
					mysql_query("INSERT INTO files (fileName, size, filetype, directory, url, date_added, date_edited, hidden, permission) VALUES ('$dirArray[$i]','".filesize($myDirectory.$dirArray[$i])."','".filetype($myDirectory.$dirArray[$i])."','".$myDirectory.$dirArray[$i]."','".$httpDirectory.$dirArray[$i]."',NOW(),NOW(),'$hiddenFile','$permission')") or die('Error: '.mysql_error());
				}
			}
		}
	}
}
//This is if the user wants to delete all the content
else {
	for ($i = 0; $i < count($dirArray); $i++){
		$fileName = $myDirectory.$dirArray[$i];
		if (!unlink($fileName)){
			echo ("Error deleting the content of the directory and the database.");
		}
	}
	while($fileName_database = mysql_fetch_array($result)){
		mysql_query("DELETE FROM files") or die("Error :".mysql_error());
	}
}
	

header("Location: ".$redirect);
?>

Any ideas? Any suggestions on improving the code is much appreciated!

I also have a question regarding the filetype() function I use to register the files in the database... is there anyway to get the same result written into the database as when you use $_POST[$fieldname] ("image/jpg" instead of just "file" as I get now)?

Thank you very much!

Recommended Answers

All 12 Replies

Well your problem is here:

if (!in_array($dirArray[$i],$fileName_database['filename'])){

The first parameter of the in_array() function should be the value to seach for, the second, the array:

if (!in_array($fileName_database['filename'],$dirArray)){

EDIT:
To fix the other problem on line 48:

if (!in_array($fileName_database['filename'],$dirArray)){

Wait, this might not work. Let me think about it for a second!

Alright, I think the problem is both of the arguments you are passing are arrays by themselves, but when you specify a part of the array, you are no longer passing an array. Maybe the in_array() isn't the function you are looking for.

Alright, I think the problem is both of the arguments you are passing are arrays by themselves, but when you specify a part of the array, you are no longer passing an array. Maybe the in_array() isn't the function you are looking for.

Yes, like you noticed are both arrays and the first value is the value of a specific position within the array.

Do you mean it might work if I get the value of the array that I want to search after into a string so I write it like in_array(string, array) and not in_array(array[specific value == string], array)?

I will try that and tell how it worked out afterwards!

Ok, I still get the same error: "parameter 2, null given..."

any ideas?

Ok, I tried this:

if (is_array($fileName_database['filename'])){
	echo "true<br />";
}
else {
	echo "false<br />";
}

Output:
false

I tried it with just $fileName_database and I received "false" as well. But why? I did fetch the array from the database on line 29:

$result = mysql_query("SELECT * FROM files");
$fileName_database = mysql_fetch_array($result);

And I do not receive the same error message when I do similar things earlier in the code:

//Checks if the user wants to delete the data or clean it
if ($option_cleanOrDelete == 'Clean'){
	#checks if the user wants the database cleaned
	if (isset($_POST['clean_database'])){
		while($fileName_database = mysql_fetch_array($result)){
			if (!in_array($fileName_database['filename'],$dirArray)){
				mysql_query("DELETE FROM files WHERE filename='$fileName_database[filename]'") or die("Error :".mysql_error());
			}
		}
	}

But here I had another condition for the loop:

while($fileName_database = mysql_fetch_array($result)){
        if (!in_array($fileName_database['filename'],$dirArray)){
...

for ($i = 0; $i < count($dirArray); $i++){
	if (!in_array($dirArray[$i],$fileName_database['filename'])){

If anyone is keen to try I've attached the script and test-files (stripped from what I want to keep private). I must say that I haven't actually tried if it works after I stripped it but I 99% sure I didn't remove anything fatal. Otherwise let me know and I will look into it, I honestly was to lazy to create a new database and test it :)

$fileName_database will not be an array if mysql_fetch_array has no result ==> it returns FALSE

But the thing is that the database table do contain several entries. So it should be an array, right?

but you run a while-loop at line 35 till its empty

but you run a while-loop at line 35 till its empty

Ok, this I didn't know, but with reservation for sounding noobish... does this delete the elements that are being read from the array?

while($fileName_database = mysql_fetch_array($result)){

In that case, what I need to is fetch the information from the database once again, right?

you can reset the pointer with mysql-data-seek

you can reset the pointer with mysql-data-seek

Should I reset the $result variable or $filename_database variable?

I guess that fixed the problem with the in_array() function! But now I have some issues when running the script. Even if both the database entry and the file exist it adds new entries into the database even though it shouldnt and if i choose to delete the files that do not have a database reference all files except one gets deleted even though they have a corresponding database entry! I can't figure out why...

Also I still wonder if its possible to achieve the "image/jpeg" result from a function similar to filetype(), like I asked about in the first post

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.