I am trying to make a php script that will rename files specified in a MySQL database to random names each time the script is executed and if the old filenames were mentioned in those files, it will replace any occurrences of the old string with the new string.
The db table has this structure:
CREATE TABLE `filenames` (
`UID` int(10) unsigned NOT NULL auto_increment,
`orig_name` varchar(100) NOT NULL default '',
`new_name` varchar(100) NOT NULL default '',
`temp_name` varchar(100) NOT NULL default '',
PRIMARY KEY (`UID`),
KEY `new_name` (`new_name`)
) TYPE=MyISAM AUTO_INCREMENT=1 ;
Nothing fancy but good enough for what needs to be done.
Almost everything is working just fine... except for one "foreach" cycle. Take a look at the below code. It's the complete script (it's far from finished though):
<?php
$db_host = "localhost";
$db_user = "xxx";
$db_pass = "xxx";
$db_name = "xxx";
function rand_name() {
$rand_name = '';
for ($i = 0; $i < 8; $i++){
$chars = array('a','b','c','d','e','f','g','h','i','j','k',
'l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
$rand_name .= $chars[rand(0, count($chars)-1)];
}
return $rand_name;
}
function db_result_to_array($query_result, $array_name) {
for ($count=0; $row = mysql_fetch_array($query_result); $count++) {
$res_array[$count] = $row[$array_name];
}
return $res_array;
}
$link = mysql_connect("$db_host", "$db_user", "$db_pass") or die
('Could not connect to MySQL server.<br>' . mysql_error());
mysql_select_db("$db_name") or die;
$query = "SELECT * FROM `filenames`";
$result = mysql_query($query);
$rows = mysql_num_rows($result);
$row = mysql_fetch_array(mysql_query($query));
$orig_name = $row["orig_name"];
$new_name = $row["new_name"];
$UID = $row["UID"];
// Update to new names code start
if ($com == 'back') { //add ?com=back to the script URL to return back to original names
update($query, $result, $echo, $back);
}else{
update($query, $result, $echo);
}
function update($query, $result, $echo = false, $back = false){
$query_result = mysql_query($query);
$query_result1 = mysql_query($query);
while ($row = mysql_fetch_array($result)) {
$orig_name = $row["orig_name"];
$new_name = $row["new_name"];
$temp_name = $row["temp_name"];
$UID = $row["UID"];
if (is_null($back)){
$rand_name = $orig_name;
}else{
$rand_name = rand_name()."$UID".".".array_pop(explode('.', $orig_name));}
mysql_query("UPDATE `filenames` SET `temp_name`='$new_name'
WHERE `orig_name`='$orig_name'");
mysql_query("UPDATE `filenames` SET `new_name`='$rand_name'
WHERE `orig_name`='$orig_name'");
// String replace & rename files code start \\
if (file_exists($new_name)) {
$query_result = mysql_query($query);
$temp_name_array = db_result_to_array($query_result, 'temp_name');
$query_result1 = mysql_query($query);
$new_name_array = db_result_to_array($query_result1, 'new_name');
// The foreach cycle below is the problematic part that needs to be fixed \\
foreach ($new_name_array AS $value){
$source = str_replace ($temp_name_array, $new_name_array,
file_get_contents($new_name));
}
file_put_contents($new_name, $source); // file_get_contents & file_put_contents is
rename ($new_name, $rand_name); // defined in external file for PHP < 5.0
}
// String replace & rename files code stop \\
if (is_null($echo)){
echo "<table align='center' width='300'><tr>
<td width='150'>$orig_name</td>
<td width='150'>$rand_name</td></tr></table>";
} } }
// Update to new names code stop
?>
Renaming files works just great without a glitch. The string replacement within the files is a problem though. Let's say there are 10 files to be replaced, all of them specified in the database. Their $orig_name, $new_name and $temp_name is initially the same so the rows look like this:
orig_name new_name temp_name
filename1.ext filename1.ext filename1.ext
filename2.ext filename2.ext filename2.ext
filename3.ext filename3.ext filename3.ext
...and so on
When you run the script, it replaces $new_name with a random name. When you run it again, it does it again and the old random name is now in the $temp_name value / db row. This is all actually working.
But when it should replace string "filename3.ext" in the body of filename2.ext, it does not because filename3.ext is in the database after filename2.ext and it doesn't replace anything after it because the foreach cycle does not know the new value yet.
Hopefully you understand what I am trying to explain. I still consider myself a newbie so I am quite sure I made a very simple mistake somewhere but just can't find it.
Any help is appreciated!
Regards,
Tomas