Is 'miked' a reserved word?

Hi All,

I’d like to share a confusing issue with a small PHP function which is not working in case $user_name = ‘miked’ - in all other cases the function is doing what it is supposed to… confusing…


function selectAvatarFromDir($user_name) {
		
	$avatars_dir = $website_path."__data/users/avatars/";
				
		$count = 0;
		if(is_dir($avatars_dir)) {
		 if($handle = opendir($avatars_dir)) {
		 while(($file = readdir($handle)) !== false) {
		 $count++;
		 }
		closedir($handle);
		}
		}
		
		$dh  = opendir($avatars_dir);
		while (false !== ($filename = readdir($dh))) {
			$files[] = $filename;
		}
		
		for ($i=1; $i<=$count; $i++) {
		$strippedName[$i] = preg_replace('/\\d*(\\..+)?/', '', $files[$i]);
		//$info = pathinfo($files[$i]);
		//$strippedName[$i] = basename($files[$i],'.'.$info['extension']); --> just tried to retrieve the 'correct' filenames, no result...
		
		$file_ext[$i] = substr($files[$i], strrpos($files[$i],".")+1);
		
		if ($strippedName[$i] == $user_name) {
			$avatar_img_src = $strippedName[$i].".".$file_ext[$i];
			}
		if ($avatar_img_src == "") { $avatar_img_src = "default_avatar.jpg"; }
		}
			
	return $avatar_img_src;
} // end function selectAvatarFromDir

As I said, when the user name is ‘miked’, the function is displaying the ‘default_avatar.jpd’ despite THERE IS the file miked.jpg in the specified folder… Why? And why it IS working for ALL the other usernames???
Thank you advanced.

That is a pretty bad way to associate avatar images with a user…very inefficient.
Why don’t you just store the location of the avatar image in the database?

I DO store the location in the database. I just thought it’s better to avoid too many calls to the database… Isn’t it?

If you are getting the username from the database what is stopping you from getting a path to an image at the same time?

I don’t know the extension of the avatar image : can be username.jpg and username.gif as well…

…I don’t see how that is relevant to storing the path to the image in the database.

Aren’t we deviating somewhat from the original question here?

Yeah, I have the same feeling… Can you please guys help me to find out why the original function won’t work with the username ‘miked’ (so far that’s the only one…). THNX

Add some print_r(), var_dump() and/or echo statements to see the actual values of the arrays and the variables. That way you should be able to see why the code does what it does.

By the way, your code is really quite confusing. You might want to optimize it. Or even better, foloow logic_earth’s suggestion, and store the image path (including the image name and extension) in the users table.

The answer to the original question is: no, miked is not a reserved word. And even if it was, the string ‘miked’ would not be reserved anyway.

I imagine so. But I felt the problem was merely a side-effect to the poorly made solution of associating a user with an image. Plus the code is mind-numing confusing.

It looks to me the problem is solved on dujmovicv’s website. But that function needs polishing.

  1. Never use uninitialized variables. Depending on your server’s configuration you will simply stress it with error log entries so ignoring this can lead to performance loss in long term. It’s also a security risk in some situations.

Uninitialized variables: $website_path, $files, $strippedName

  1. I would trim down the function like this:
<?php
function selectAvatarFromDir($user_name) {

	global $website_path; // if it's set outside the function
						// you have to make a global reference to it
						// or your function won't be aware of it
	$avatars_dir = $website_path."__data/users/avatars/";

	$files = array();
	if (is_dir($avatars_dir)) {
		if ($handle = opendir($avatars_dir)) {
			while(($file = readdir($handle)) !== false) {
				if ($file != "." && $file != "..") $files[] = $file;
			}
			closedir($handle);
		}
	}

	return in_array($user_name, $files) ? $user_name : "default_avatar.jpg";
} // end function selectAvatarFromDir
?>

Why? Well… it’s just wrong to readdir twice when you can do it in one step. Second, you can easily check the $user_name in an array rather than going through some time consuming routine check.

But the readdir is not exactly a good practice. I would rather change the update_avatar function to rebuild the cache everytime a user changes his avatar, the this function wouldn’t have to read the whole avatars directory but a single file, which is definitely better considering in a page displaying more avatars you really stress the HDD in that server with a lot of readdirs.

Even better, I would pull out the avatar cache from that function and put it in a top level include that will generate a constant as the array of your users’ avatars. Something like this:

$avatars_dir = $website_path."__data/users/avatars/";

$files = array();
if (is_dir($avatars_dir)) {
	if ($handle = opendir($avatars_dir)) {
		while(($file = readdir($handle)) !== false) {
			if ($file != "." && $file != "..") $files[] = $file;
		}
		closedir($handle);
	}
}

define("AVATAR_CACHE", $files);

After this, your function would look like:

function selectAvatarFromDir($user_name) {

	return in_array($user_name, AVATAR_CACHE) ? $user_name : "default_avatar.jpg";
} // end function selectAvatarFromDir

Thanks guys! All your posts were helpful, especially kneekoo’s! I’ll have to decide which option to choose : readdir or database calls… I think I have optimized the code for both cases now (thanks to you)!