I am trying to write a function that counts the image while looping through the files for one case (out of many cases), I declared the variable $imageCount global within the function copyInsertImage so that after the image is successfully inserted into the database, I do an $imageCount++.
After processing all the images for the case, the code exits the loop, the function processImages will be recalled again. However, I did a var_dump($imageCount) to print out the image count each time it gets increased by one, and found out that it was never reset back to 0 by the $imageCount = 0 when running the loop for a new case.
I am wondering if declaring global $imageCount has anything to do with it, because the code worked fine previously before grouping the same script into a function. If so, what is the solution?
Thanks!
function processImages($path,$patientID,$caseID)
{
// $path = rootDirectory/patientID
global $targetDirectory;
$targetPath = $targetDirectory.$patientID;
$caseSummaryFolder = $path."/".$caseID."/Summary";
$srcDirPath=$path."/".$caseID."/Summary/slicesdir"; //AKA src
$dstDirPath = $targetPath."/".$caseID;
//copyCaseImages($caseSummaryFolder,$targetCasePath,$patientID,$caseID);
global $status;
// print("processImages case path:".$casePath."</br>");
$files = glob($srcDirPath."/*.png");
echo "\n------------NEW CASE------------\n"
echo "PATIENT: $patientID \n";
echo "CASE: $caseID \n";
echo "--------------------------------\n"
$imageCount = 0;
for($i = 0; $i < count($files); $i++) {
$file = $files[$i];
$fileName = str_ireplace($srcDirPath."/", "", $file);
// if image name doesn't not contain string 'GROT'
if(strripos($fileName, "grot") === false)
{
if(doesImgExist($fileName)!==NULL) {
if (compareFileMTime($srcDirPath,$fileName,doesImgExist($fileName))) {
echo "There's a newer version of $fileName \n";
copyInsertImage($srcDirPath,$dstDirPath,$fileName,$patientID,$caseID);
}
else {
$imageCount++;
}
}
// copy image to analyzedCp and insert new image into DB
else {
copyInsertImage($srcDirPath,$dstDirPath,$fileName,$patientID,$caseID);
}
}
else {
echo "grot*.png files are not included \n";
}
}
If I understood your question correctly, it seems like you are redeclaring "global $imageCount" inside of your "copyInsertImage" function and this function is part of the for-loop. If this is indeed what you have then a problem is that everything time your for-loop hits the "copyInsertImage" function it will take re-declare $imageCount, this re-declaration will make imageCount a new variable and clear whatever you have stored in it. This could be the reason why you are seeing $imageCount = 0.
#andrewsi Answered my question.
My question was solved by declaring the initial $imageCount as global too.
"if you're using globals, you need to declare them as global in every function that uses them. Otherwise, you end up using a local variable with the same name. This is one of the reasons to try to avoid them if possible - it's easier to pass variables into functions when you need them."
Thanks!
Related
This question already has answers here:
Reference: What is variable scope, which variables are accessible from where and what are "undefined variable" errors?
(3 answers)
Closed 4 years ago.
I'd like to report how many files get deleted from a function that I'm running within php via a cron task.
Current codes is as follows:-
<?php
function deleteAll($dir) {
$counter = 0;
foreach(glob($dir . '/*') as $file) {
if(is_dir($file)) {
deleteAll($file); }
else {
if(is_file($file)){
// check if file older than 14 days
if((time() - filemtime($file)) > (60 * 60 * 24 * 14)) {
$counter = $counter + 1;
unlink($file);
}
}
}
}
}
deleteAll("directory_name");
// Write to log file to confirm completed
$fp = fopen("logthis.txt", "a");
fwrite($fp, $counter." files deleted."."\n");
fclose($fp);
?>
That makes sense to me with a VBA background, but the counter returns null I think when written to my custom log file at the end. I presume there is some restriction on a shared hosting site of being able to declare the variable globally or similar?
Appreciate any help! It's not the end of world if I can't count the deleted files, but it would be nice to log the output in the format I've chosen.
This doesnt work due to scopes. In your example $counter only exists inside your function.
function deleteAll($dir):int {
$counter = 0; // start with zero
/* Some code here */
if(is_dir($file)) {
$counter += deleteAll($file); // also increase with the recursive amount
}
/* Some more code here */
return $counter; // return the counter (at the end of the function
}
$filesRemoved = deleteAll("directory_name");
Alternatively, if you want to send back more info, eg 'totalCheck' etc, you can send back an array of info:
function deleteAll($dir):array {
// All code here
return [
'counter' => $counter,
'totalFiles' => $allFilesCount
];
}
$removalStats = deleteAll("directory_name");
echo $removalStats['counter'].'files removed, total: '.$removalStats['totalFiles'];
There are other solutions like 'pass-by-reference', but you dont want those.
I adopted code from https://stackoverflow.com/a/44553006/8719001
but can't figure out why when uploading the same file "test.jpg" several times it only counts up once, creating "test-1.jpg" but not more ie. test-2.jpg, test-3.jpg.
Can anybody spot the issue and help please?
$keepFilesSeperator = "-";
$keepFilesNumberStart = 1;
if (isset($_FILES['upload'])) {
// Be careful about all the data that it's sent!!!
// Check that the user is authenticated, that the file isn't too big,
// that it matches the kind of allowed resources...
$name = $_FILES['upload']['name'];
//If overwriteFiles is true, files will be overwritten automatically.
if(!$overwriteFiles)
{
$ext = ".".pathinfo($name, PATHINFO_EXTENSION);
// Check if file exists, if it does loop through numbers until it doesn't.
// reassign name at the end, if it does exist.
if(file_exists($basePath.$name))
{
$operator = $keepFilesNumberStart;
//loop until file does not exist, every loop changes the operator to a different value.
while(file_exists($basePath.$name.$keepFilesSeperator.$operator))
{
$operator++;
}
$name = rtrim($name, $ext).$keepFilesSeperator.$operator.$ext;
}
}
move_uploaded_file($_FILES["upload"]["tmp_name"], $basePath . $name);
}
your while loop condition has a problem
while( file_exists( $basePath.$name.$keepFilesSeperator.$operator ) )
the $name variable still contains the full name of file, in this case test.jpg, you're testing a value like /home/test.jpg-1 so finally the while loop is never executed as the file test.jpg-1 never exists, that's why you always get the test-1.jpg on disk and not a ...-2.jpg or ...-3.jpg
A while ago I made a post (Searching for a specific string from all PHP files in the parent directory) that was about me finding the position of the file path in an array, only if the file had a specific keyword.
However, that was in my old website, which I have now lost. So I am currently recreating it. However, for some reason this function does not work.
public function build_active_theme() {
$dir = CONPATH . '/themes/' . $this->get_active_theme() . '/';
$theme_files = array();
foreach(glob($dir . '*.php') as $file) {
$theme_files[] = $file;
}
$count = null;
foreach($theme_files as $file) {
$file_contents = file_get_contents($file);
if(strpos($file_contents, 'Main')) {
$array_pos = $count;
$main_file = $theme_files[$array_pos];
echo $main_file;
}
$count++;
}
}
This function causes the following error:
Notice: Undefined index: in /home/u841326920/public_html/includes/class.themes.php on line 30
I have narrowed the problem down the something wrong with the $count variable. Whenever I try and echo the $count value once the script has found the correct file, nothing is shown.
But after spending nearly an hour on such a simple problem, it is obviously starting to frustrate me, so I am now seeking help.
(Note: I directly copied the function directly from the old post into my code, and made the appropriate changes to variables to 'work' in the new site, so it's is pretty much exactly the same as the solution that fixed my previous problem - which funnily enough was also caused by the $count variable).
Thanks,
Kieron
You can use the foreach $key instead of a separate count variable, try the code below:
foreach($theme_files as $key => $file) {
$file_contents = file_get_contents($file);
if(strpos($file_contents, 'Main') !== false) {
$main_file = $theme_files[$key];
echo $main_file;
}
}
You are setting
$count = null;
, try to ++ it before the
$array_pos = $count;
I want to get a random background image using php. Thats done easy (Source):
<?php
$bg = array('bg-01.jpg', 'bg-02.jpg', 'bg-03.jpg', 'bg-04.jpg', 'bg-05.jpg', 'bg-06.jpg', 'bg-07.jpg' );
$i = rand(0, count($bg)-1);
$selectedBg = "$bg[$i]";
?>
Lets optimize it to choose all background-images possible inside a folder:
function randImage($path)
{
if (is_dir($path))
{
$folder = glob($path); // will grab every files in the current directory
$arrayImage = array(); // create an empty array
// read throught all files
foreach ($folder as $img)
{
// check file mime type like (jpeg,jpg,gif,png), you can limit or allow certain file type
if (preg_match('/[.](jpeg|jpg|gif|png)$/i', basename($img))) { $arrayImage[] = $img; }
}
return($arrayImage); // return every images back as an array
}
else
{
return('Undefine folder.');
}
}
$bkgd = randImage('image/');
$i = rand(0, count($bkgd)-1); // while generate a random array
$myRandBkgd = "$bkgd[$i]"; // set variable equal to which random filename was chosen
As I am using this inside a wordpress theme, I need to set the $bkgd = randImage('image/'); relative to my theme folder. I thought, I could do that using:
$bgfolder = get_template_directory_uri() . '/images/backgrounds/';
bkgd = randImage($bgfolder);
When I test $bgfolder, which seems to be the most important part, using var_dump() I receive a not working path:
http://yw.hiamovi-client.com/wp-content/themes/youthwork string(19) "/images/backgrounds"
Somehow there is a space before the /images/backgrounds/. I have no idea where this comes from! …?
You'll want to change
$myRandBkgd = "$bkgd[$i]";
to
$myRandBkgd = $bkgd[$i];
If that doesn't help, use var_dump() instead of echo() to dump some of your variables along the way and check if the output corresponds to your expectations.
I am using this script to delete picture from my server. But at the same time I want to protect the files in my server. Not accidentally delete but I noticed that if I typed the file index.pHp or index.Php is deleted from my server. Although setting it will not delete why php or this method not know between lowercase and uppercase.
What is not done right?
<?php
error_reporting (0);
$thefile = $_GET ['filetodel'];
$filename = "$thefile";
//$filename = "picture1.jpg";
/*protect some files*/
if ($thefile=='index.php' or $thefile=='INDEX.PHP' or $thefile=='UPLOADS.ZIP' or $thefile=='uploads.zip' or $thefile=='del.php'or $thefile=='DEL.PHP' or $thefile==NULL or $thefile=='.htaccess' or $thefile=='.HTACCESS' )
{
exit("<h2>cannot delete $thefile</h2>");
}
if ($thefile=="$thefile")
{
if (file_exists($filename))
{
unlink ("$thefile");
echo "<h2> file $thefile is delete</h2>";
}
else
{
echo "<h2>The<br>";
echo "$filename<br>";
echo "Does not exist</h2>";
}
}
?>
Just convert the input to lowercase and test it once, rather than worrying about every possible mix of case:
if (strtolower($thefile) == 'index.php') {
// ...
}
For the next iteration, you could store your protected files in an array:
$protected_files = array('index.php', 'uploads.zip', 'del.php', '.htaccess');
if (in_array(strtolower($thefile), $protected_files) || $thefile==NULL) {
// ...
}
the problem is here:
if ($thefile=="$thefile")
as if your 1st condition for file check is false than the second condition is
if ($thefile=="$thefile")
which is always true so it will unlink the file
Also add one line as below just before 1st condition
$thefile = strtolower($thefile);