Why is $count not updating? - php

$dir_handle = #opendir($url) or die("Unable to open $url");
$count = "0";
while ($file = readdir($dir_handle)) {
if (!is_dir($url.'/'.$file) && ($file="*.jpg" || $file="*.gif" || $file="*.png") && $file!="picture0.*") {
$galleryEventFile[$count] = $file;
$count++;
}
}
closedir($dir_handle);
I think it has something to do with this line:
if (!is_dir($url.'/'.$file) && ($file="*.jpg" || $file="*.gif" || $file="*.png") && $file!="picture0.*")
but im not sure

I can see two things that will be causing you problems:
Assignment/comparison:
You have the code:
if ($file="*.jpg" //etc...
However, a single equal sign will perform an assignment, not a comparison - you need to use two equals signs (==) for this. See http://php.net/manual/en/language.operators.comparison.php. Essentially what you are doing by doing an assignment in an if statement is:
$file = '*.jpg';
if ($file) { }
Wildcard matching of strings
You also can't do wildcard matching like that ($file == "*.jpg) on a string, you could look at using preg_match() and regular expressions instead, e.g.
if (!preg_match('/\.jpg$/i', $file)) {
//not .jpg
}
It might be better to do something like this though:
//get file extension
$extension = pathinfo($file, PATHINFO_EXTENSION);
$allowedExtensions = array('jpg', 'png', 'gif');
//check in allowed list
if (!in_array(strtolower($extension), $allowedExtensions)) {
//not valid
}

First, $count should be a number. Do:
$count = 0;
Second, AFAIK, PHP doesn't support wildcard matching like that. You can't use "*" to match. You'll need to use regular expressions to match in the conditional.

Do as thedz and Tom Haigh have suggested.
Have you also heard about XDebug? This will allow you to setup an environment say using Eclipse and step through your PHP code. I do not develop without using a combination Eclipse and XDebug.

The first thing you want to do is to debug the if line. Remember that if you put *.gif, it is looking to see that the file is actually named "*.gif", rather than looking for 'any' gif file, similar to what Windows does.
What I'd suggest is going through each segment of the if, and get it to pass. then you can start putting it together.

Related

Edit PHP code to use strpos to find if Big and Needle1 are in filename

Apologies, I screwed up on title and question, I believe both are now fixed. It looked like I was looking for "OR", whereas I am looking for "AND".
I have several files in a folder:
this-is-big-needle1.jpg
a-big-long-needle1.jpg
this-file-is-needle2.jpg
needle3-is-this-file.jpg
The current code && strpos($file,"needle1") is used to search a folder and inlcude all files that that match the strops value eg "needle1" and include these images in an AMP HTML carousel.
So current code searches for "needle1" and will correctly return the first 2 files above but ignore the others.
I have searched and found several general solutions for finding if needle1 OR needle2 are present in filename, but found nothing were both "big" and "needle1" are found in the same filename.
I have tried adding a second strops && strpos($file, "needle1") && strpos($file, "big") but my php skills are very lacking so get easily tripped up with syntax and were to put eg '..' etc
php
$Count5Image5 = 0;
$Image5;
$handle = opendir(dirname(realpath(__FILE__)).'/images/');
while($file = readdir($handle)){
if($file !== '.' && $file !== '..' && strpos($file,"needle1"))
{
Image5[$Count5Image5] = $file;
$Count5Image5++;
}
}
sort($Image5);
for($i=0; $i<$Count5Image5; $i++)
echo '<amp-img src="images/'.$Image5[$i].'" class="xs-12" width="353" height="210" layout="responsive"></amp-img>';
?>
If someone could suggest an edit of my code to find "big" & "needle1" in the same filename (to return top two files) it would be appreciated.
==========
A litte side issue (in case there is an obvious solution) - for some reason existing code will not find any file if the strops value is at the start of the file name eg if I enter value "this-" it will not find any files or if I enter needle3 it will not find any files (string must be after character1 in the string)
Maybe you can replace:
if($file !== '.' && $file !== '..' && strpos($file,"needle1"))
With:
if($file !== '.' && $file !== '..' && ( strpos($file,"needle1") !== false || strpos($file,"needle2") !== false )
This would match all files having needle1 or needle2 in the name.
Please note the !== false I added after each strpos(). This helps you with the side issue you mentioned. strpos returns false if needle is not found and 0 in case the filename starts with the needle. They both evaluate as false in an if statement context ( you can read more here ).
Preg_match alternative
This would be another nice way to match both big and needle no matter the order in which they appear in the filename.
if(preg_match("/(big|needle1)/i", $file) !== 0) {
}
This would match both: this-is-big-needle1.jpg and this-needle1-is-big.jpg as can be seen here: regex test
Alternative
Another nice way of doing it would be to use the glob() function:
That way you could only get the files that match those filenames:
foreach (glob("{*needle1*,*needle2*}.*", GLOB_BRACE) as $filename) {
echo $filename."<br />";
}
Hope that helps.
The issue you are running into is the one the manual references,
This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE. Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.
-https://www.php.net/manual/en/function.strpos.php
So !== is what you should use for the comparison.
Since you are doing pattern matching though I would just use a regex with preg_match.
preg_match('/needle[12]/', $file)
The [] is a character class and allows all characters listed inside it, with some exceptions, https://www.regular-expressions.info/charclass.html.

How can I check if a file exists with a certain string in its filename?

I'd like to be able to search a directory for a file that starts with a specific string, for example:
- foo
- 1_foo.jpg
- 2_bar.png
How would I check directory foo for files that begin with "1_"?
I've tried using file_exists and preg_match like so:
if (file_exists("foo/" . preg_match("/^1_/", "foo/*"))) echo "File exists.";
but this doesn't work.
Sounds like you need the glob() function. The glob() function searches for all the pathnames matching pattern according to the rules used by the libc glob() function, which is similar to the rules used by common shells.
<?php
foreach (glob('1_*.*') as $filename) {
echo "$filename\n";
}
?>
The above example will output something similar to:
1_foo.png
1_bar.png
1_something.png
Sorry, but the filesystem doesn't understand wildcards or regular expressions. To accomplish what you want, you have to open the directory and read its contents, getting a list of all the files in that directory. Then you use standard string utilities to see which filenames match your criteria.
I think PHP's scandir is what you want as a starting point. You can also use glob but that actually forks a shell to get the file list (which in turn will do the C equivalent of scandir()).
You can use the glob() function
<?php
$list = glob('1_*.*');
var_dump($list);
I was having some trouble checking a directory and files and I gather some scripts here and there and this worked for me (Hope it helps u too):
if ($handle = opendir('path/to/folder/'))
{
while ( false !== ($entry = readdir($handle)) ) {
if ( $entry != "." && $entry != ".." ) {
// echo "$entry<br>";
if (preg_match("/^filename[0-9]_[0-9].jpg/", $entry))
{
// $found_it = TRUE;
}
}
}
closedir($handle);
}

When using readdir empty strings returned

I am using readdir in the following code to get a list of all file names of images in a directory.
while (false !== ($entry = readdir($frameDir))){
$shapeName = explode('.',$entry);
if (!empty($shapeName[0]) && $shapeName[0] != '.' && $shapeName[0] != '..' && $shapeName[0] != '/'){
$shapeName = $shapeName[0];
$shapes['frames'][] = $shapeName;
}
After this code the script appends the '.png' to make it a valid file name.
As you can see I've tried to eliminate any chances of a blank file name being passed. Though when I run the script I end up getting a blank directory "/shapes/frame/.png" . This only happens for this particular directory. When I use the code on another of the three directories I get results as expected, and the code is the same logic as what is used above.
while (false !== ($entry = readdir($frameDotDir))){
$shapeName = explode('.',$entry);
if (!empty($shapeName[0]) && $shapeName[0] != '.' && $shapeName[0] != '..' && $shapeName[0] != '/'){
$shapeName = $shapeName[0];
$shapes['frame_dots'][] = $entry;
}
}
When checking the filesystem on the server, I can't find any files with blank names.
I am wondering what could be causing my script to be reading blank file names from the diretory.
File names cannot be empty (and will not). You did something wrong in your code. It should look like:
while ($entry = readdir($frameDir)){
// skip files which names starting with a dot
// like '.', '..' or hidden files
if (strpos($entry, '.') !== 0) {
$shapes['frame_dots'][] = $entry;
}
}
You see, less is more ;)
Why don't you use glob() instead of readdir().Just give it a pattern and it will let you process the filenames with much ease instead of doing the one by one scanning work. And in your case, there is no way it will return an empty file name. Also, have a look on glob flags in the documentation, you will be amazed of it's simplicity.
glob("*.png");
Output:
Array ( [0] => shape.png, [1] => shape2.png )
I was having the same problem with blank filenames usind readdir() it turn out to be that the directory name was wrong, turns out linux is case sensitive, in code the directory name starts with "I" and in linux the directory started with "i".
I guess the error was due to not handling opendir() errors. Check your code.

How to check portion of a string and accept anything after it?

I had a hard time wording this question. Lets say you have two things in a database:
-"String"
-"Stringify"
In PHP, you use this:
"SELECT * WHERE string = stri%"
This would return both of the strings in the database because the % [percentage sign] is the responsible one for checking if the values have those four letters [stri] and accepting them since the rest doesn't matter.
That's not the question. Is there something like that [%] in jQuery?
I have the following code.
if (ext == "jpg" || ext == "gif") {
} else {
ext = ext + ".jpg";
}
Many times, my JSON might return something like this:
nameofimage.jpg?1
This is ignored because jpg?1 is NOT equals to jpg but it is still a jpg. This is why I am asking... Is there anything that can be used to check only the first three letters of the extension and ignore the rest?
Something like this:
if (ext == "jpg%" || ext == "gif%") {
//Do nothing, it's already a jpg or a gif
} else {
ext = ext + ".jpg";
}
I tried my very best to word this the right way. I hope someone here can help me. Thank you.
Try string.contains()
if(ext.contains(".jpg") || ext.contains(".gif")) {
I think the method you are looking for is indexOf():
if (ext.indexOf('jpg') !== -1 || ext.indexOf('gif') !== -1) {
// true
}
However it is a bit cleaner and safer to not just check for the extension but the whole filename as well. Imagine this filename: "somejpg.exe". The above method would consider it as a "jpg" where as it is not. The easiest to use regular expressions for these kind of things:
/\.(jpg|gif|png|bmp)$/.test('test.png'); // => true
/\.(jpg|gif|png|bmp)$/.test('test.gif'); // => true
/\.(jpg|gif|png|bmp)$/.test('hack_jpg.exe'); // => false

Will this only allow certain extensions?

I found this snippet that says will only allow certain file types. Will it work and could someone bypass it to upload what ever file type they want? And could someone explain the substr part, i don't get how it works..
<?php
function CheckExt($filename, $ext) {
$name = strtolower($filename);
if(substr($name, strlen($name) -3, 3) == $ext)
return true;
else
return false;
}
?>
A better way to check extensions
function checkExt($filename, $ext)
{
$fnExt = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if(!is_array($ext)) {
$ext = (array)$ext;
}
$ext = array_map('strtolower', $ext);
return in_array($fnExt, $ext);
}
You can then call it like
var_dump(checkExt('test.temp', 'tmp')); // false
var_dump(checkExt('test.temp', array('tmp', 'temp'))); // true
Avoid using substr as the extension length is unknown (you can use substr & strrpos as well but php provides this functionality for you)
It's very easy to bypass as changing the extension of a file does not change the contents of the file. So a .exe renamed into a .jpg is still an .exe waiting to be run anyway. You can use it for a basic check, but don't rely solely on it to validate file types.
This substr() call:
substr($name, strlen($name) -3, 3)
Is better more simply written as:
substr($name, -3)
Which PHP just interprets as 'take only the last 3 characters of $name'.
EDIT: it's not better per se because file extensions don't necessarily have to be 3 characters long. They could be 2, they could be 4, 5, even 10. This is why as I said, checking file extensions isn't very reliable.
I prefer to whitelist the Mimetypes I want to allow using something along the lines of
$mimesGeneral = array(
'txt'=>'text/plain',
'doc'=>'application/msword',
'pdf'=>'application/pdf',
'xls'=>'application/x-excel',
'xls'=>'application/excel',
'xls'=>'application/vnd.ms-excel',
'rtf'=>'application/rtf',
'zip'=>'application/zip'
);
$success = false;
foreach($allowedMimes as $key=>$value){
if($_FILES['uploaded_file']['type'] == $value){
return true;
}
}
I use this with a blacklist of suffixes e.g 'php', 'pl', 'exe' etc...
People will still be able to upload whatever they want; they just have to give the file a particular extension.
For substr, see the manual.

Categories