PDA

View Full Version : PHP simple but annoying problem




Soulstorm
Sep 29, 2008, 07:40 AM
I recently started learning PHP, and I am having some problems with it. Look at this code:


$clients = array();
$userFile = './users.txt';

if (is_readable($userFile) == false){
print "it still is not readable";
}

get_clients($clients, $userFile);


function get_clients(&$clientArr, $fileName){
if(is_readable($filename) == true){
$fp = fopen($fileName, "r");
}
else
{
print 'error. file is not readable';
}
}

The problem is that the code inside the function generated an error about users.txt being unreadable, while the code outside the function (which does the same thing) does not generate a problem at all! users.txt is a file in the same directory as the file that contains this php code, and I am very sure I have given it the correct permissions to be readable and writable through OS X (I have installed a PHP server on my machine using XAMPP).

Can anyone help me with this?



itickings
Sep 29, 2008, 08:19 AM
My guess would be that $filename and $fileName are in fact two completely different variables.

$fileName contains the "./users.txt", and $filename does not.

toddburch
Sep 29, 2008, 08:20 AM
function get_clients(&$clientArr, $fileName){
if(is_readable($filename) == true){


Typo in code?

Soulstorm
Sep 29, 2008, 08:44 AM
So it was because of my stupidity after all.. Sorry for wasting your time, guys.

Actually, I have another, more serious problem, and I don't want to start a new thread about it, so I am posting it here.

This is readusers.php:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
</head>

<body>
<p>
<?php
class ClientInfo{
public $password;
public $description;
public $url;

public function setVars($newPass, $newDescription, $newURL){
$this->password = $newPass;
$this->description = $newDescription;
$this->url = $newURL;
}

public function setPass($newPass){
$this->password = $newPass;
}

public function foo($arg){
print $arg;
}

}

$clients = array();
$userFile = "./users.txt";

if (is_readable($userFile) == false){
print "it still is not readable";
}


get_clients($clients, $userFile);


function get_clients(&$clientArr, $fileName){
if(is_readable($fileName) == false){
print 'error. file is not readable';
}
else
{
$fp = fopen($fileName, "r");
if($fp){
$arr = array();
$buffer;
while (!feof($fp)){
$buffer = fgets($fp);
if (strlen($buffer) >1 ){
$arr[] = $buffer;
}
}
fclose($fp);


foreach($arr as $line){
if( strpos($line,'new_user') != false){
$clientArr[] = new ClientInfo();

}
if( strpos($line, 'name:',0) != false){
//print 'found a name! <br />';
$nameStartLocation = strpos($line, ':') + 1;
$strLength = strlen($line);
$nameString = substr($line, $nameStartLocation, $strLength - $nameStartLocation - 1);
end($clientArr)->password = $nameString;
}
if( strpos($line, 'url:',0) != false){
//print 'found a name! <br />';
$urlStartLocation = strpos($line, ':') + 1;
$strLength = strlen($line);
$urlString = substr($line, $urlStartLocation, $strLength - $urlStartLocation - 1);
end($clientArr)->url = $urlString;
}
if( strpos($line, 'desc:',0) != false){
//print 'found a name! <br />';
$descStartLocation = strpos($line, ':') + 1;
$strLength = strlen($line);
$descString = substr($line, $descStartLocation, $strLength - $descStartLocation - 1);
end($clientArr)->description = $descString;
}
}
}
}
}
if($clients[0]->password == 'doit') echo "hellO!";
echo $clients[0]->password;
?>

</body>
</html>


This is users.txt
**new_user
-name:doit
-desc:hello world
-url:www.kkk.com
**end_user

**new_user
-name:doit2
-desc:hello world2
-url:www.kkk.com2
**end_user

It appears that the file is read correctly. I even tried to output the variables. However, why the line "if($clients[0]->password == 'doit') echo "hellO!";" gives no output? Has it something to do with the file not being read correctly? Or is it an encoding problem?

itickings
Sep 29, 2008, 09:10 AM
It appears that the file is read correctly. I even tried to output the variables. However, why the line "if($clients[0]->password == 'doit') echo "hellO!";" gives no output? Has it something to do with the file not being read correctly? Or is it an encoding problem?

I pasted your code into files, ran it and got "hellO!doit" as output.

Comparing strings with == isn't really recommended though, and the output isn't valid XHTML since the <p> tag is left open. Some browsers may refuse to render invalid XHTML.

toddburch
Sep 29, 2008, 09:33 AM
That's interesting. I get this after pasting:

Parse error: parse error, expecting `T_OLD_FUNCTION' or `T_FUNCTION' or `T_VAR' or `'}'' in /Users/toddburch/Sites/readusers.php on line 12

Sarafi on Tiger 10.4.11 (and on FireFox)

(Edit - well, my errors are because I'm not on PHP 5, I'm still on 4.4.8)

Soulstorm
Sep 29, 2008, 10:04 AM
I pasted your code into files, ran it and got "hellO!doit" as output.

Comparing strings with == isn't really recommended though, and the output isn't valid XHTML since the <p> tag is left open. Some browsers may refuse to render invalid XHTML.

That's strange... What system do you use, and what version of PHP? Also, how did you install PHP? I am using xampp.

Actually, I have noticed that php on my machine behaves slightly differently than the one on my web server (the one where my site is hosted).

More accurately, the following code is an part of the one I have given you:

if( strpos($line, 'name:',0) != false){
//print 'found a name! <br />';
$nameStartLocation = strpos($line, ':') + 1;
$strLength = strlen($line);
$nameString = substr($line, $nameStartLocation, $strLength - $nameStartLocation - 1);
end($clientArr)->password = $nameString;
}
if( strpos($line, 'url:',0) != false){
//print 'found a name! <br />';
$urlStartLocation = strpos($line, ':') + 1;
$strLength = strlen($line);
$urlString = substr($line, $urlStartLocation, $strLength - $urlStartLocation - 1);
end($clientArr)->url = $urlString;
}
if( strpos($line, 'desc:',0) != false){
//print 'found a name! <br />';
$descStartLocation = strpos($line, ':') + 1;
$strLength = strlen($line);
$descString = substr($line, $descStartLocation, $strLength - $descStartLocation - 1);
end($clientArr)->description = $descString;
}

That works on my web server but not on my machine! In order to get the correct output, I must use:

if( strpos($line, 'name:',0) != false){
//print 'found a name! <br />';
$nameStartLocation = strpos($line, ':') + 1;
$strLength = strlen($line);
$nameString = substr($line, $nameStartLocation, $strLength - $nameStartLocation - 2);
end($clientArr)->password = $nameString;
}
if( strpos($line, 'url:',0) != false){
//print 'found a name! <br />';
$urlStartLocation = strpos($line, ':') + 1;
$strLength = strlen($line);
$urlString = substr($line, $urlStartLocation, $strLength - $urlStartLocation - 2);
end($clientArr)->url = $urlString;
}
if( strpos($line, 'desc:',0) != false){
//print 'found a name! <br />';
$descStartLocation = strpos($line, ':') + 1;
$strLength = strlen($line);
$descString = substr($line, $descStartLocation, $strLength - $descStartLocation - 2);
end($clientArr)->description = $descString;
}

...which means that on my computer I must read one character less in order to properly read the data. Does it have something to do with line endings?

toddburch
Sep 29, 2008, 10:45 AM
If it is line endings, I would take care of those first (remove them) and then your code is more portable.

Also, why not "else if" on the last two ifs? Will the user.txt file have multiple entries on a single line?

Soulstorm
Sep 29, 2008, 10:59 AM
If it is line endings, I would take care of those first (remove them) and then your code is more portable.

How do I remove line endings from a .txt file? I thought that these are automatically generated... Here (http://www.programmingforums.org/attachment.php?attachmentid=729&d=1222704705) is my entire project in case you want to try it out yourself.

toddburch
Sep 29, 2008, 11:07 AM
See here: http://us3.php.net/manual/en/function.fgets.php

and read the Notes and Mac line endings. Maybe that's it.

Soulstorm
Sep 29, 2008, 11:17 AM
I have enabled "auto_detect_line_endings" to no effect. May I ask how do you use PHP on your system? It seems that the fault must be in my PHP configuration. Do you use the built-in configuration of OS X?

toddburch
Sep 29, 2008, 11:42 AM
Yes, I'm just using the default config. My auto_detect has a value of 0.

I've attached my phpinfo file, FWIW.

I would suggesting printing out the hex codes of your lines to see what is different on both platforms. That would confirm it was or wasn't the line ending chars.

Soulstorm
Sep 29, 2008, 12:58 PM
problem solved. Actually, there are differences between my configuration and the one at my web server. My machine thought line endings were '\n', while my web server thinks they are "\r\n". So, instead of tackling with the configurations, I decided to alter my script, so that it works in all cases:

foreach ($clientArray as $key => $value){
$fixedString = $password . "\r";
if( (strcmp($clientArray[$key]->password,$password) == 0) or (strcmp($clientArray[$key]->password,$fixedString) == 0) ){
print '<meta HTTP-EQUIV="REFRESH" content="1; url=' . $clientArray[$key]->url . '">';
$introText = 'Client is: "'. $clientArray[$key]->description . '" Redirecting now...';
$isValid = true;
}
elseif( strcmp($password,'purge_log') == 0){
purgeLog($logFile);
}
}

and now it works in both cases.

Yes, I'm just using the default config. My auto_detect has a value of 0.

So, I suggest you enable php from the terminal and you put files in your "sites" folder?

toddburch
Sep 29, 2008, 02:47 PM
Yes, I have my files in the /Users/me/Sites folder. I enabled PHP from the Apache config file. I have Personal Web Sharing on. I'm able to get to my Mac's localhost from all the machines in my home network.

I also have files in Mac HD/Library/WebServer/... for testing out CGI scripts and whatnot in a more real-to-lib environment where permissions count.