Page 1 of 1

[solved] Fatal error: Call to a member function

Posted: Mon Jul 02, 2007 3:50 pm
by m2babaey
Hi
since I was kept receiving the error " headers alread sent" in my login code, I decided to separate the from from its action.
I'm getting this error now: is there a way to fix it?:
Fatal error: Call to a member function on a non-object in g:\programs(2)\easyphp1-8\www\ha\previous\new folder\another\htdocs\loginaction.php on line 4
codes are here
the for action code:
loginaction.php:

Code: Select all

<?php
include('global.php');
include('html_form.php');
	if ($form->valid()) {
		$processed = $form->getProcessed();
		$remember = $form->getValue('remember');

		if (!isset($_SESSION['login'])) {
			$_SESSION['login'] = 3;
		} else {
			if ($_SESSION['login'] <= 1) {
				die('You cannot log in.');
			}
		}

		if ($user->_checkLogin($processed['username'], $processed['password'], $remember)) {
			if (isset($_SESSION['log_to'])) {

				header("Location: {$_SESSION['log_to']}");
exit;
			} else {
	
				header("Location: account.php");
				exit;
			}
		} else {
			failed($form);
		}

	} else {
		begin_html();
		$form->display();
	}

	function failed(&$form) {
		begin_html();
		echo "<p>You could not be logged in, $_SESSION[login] attempts left.</p>
		<p>Possible reasons for this are:</p>

		<ul>
			<li>Your username and/or password is not correct.
				Check your username and password and then try again.</li>
			<li>You haven't " .
			'<a href="signup.php" title="Sign up for an account, it is free">registered</a> yet</li>
			<li>Your account is temporarily disabled.</li>
			<li>You are trying to login simultaneously from two different computers or
			two browsers on the same computer.</li>
		</ul>';

		
	}
?>
and the form:

Code: Select all

<?	require_once 'global.php'; 

if ($_SESSION['logged']) {
include('clean.php');
		redirect('account.php');
	}
	else{
?><html>

<head>
<meta http-equiv="Content-Language" content="fa">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>left menu</title>
</head>

<body>

<table border="1" width="100%" id="table1" height="346">
	<tr>
		<td width="97" height="37">left menu</td>
		<td height="37">
		<p align="center">I'd like items here</td>
		<td width="148" height="37">right menu</td>
	</tr>
	<tr>
		<td width="97">my menu</td>
		<td><?php
   
/* $Id: login.php,v 1.7 2002/09/03 22:02:01 shaggy Exp $ */




	require_once 'html_form.php';
	define("act","loginaction.php");
	$form = new Form(act);

	$form->addText('username', '&#1588;&#1606;&#1575;&#1587;&#1607; &#1603;&#1575;&#1585;&#1576;&#1585;&#1610;');
	$form->addPassword('password', '&#1585;&#1605;&#1586; &#1593;&#1576;&#1608;&#1585;');
	$form->addCheckbox('remember', 'Remember me');

	$form->addSubmit('&#1608;&#1585;&#1608;&#1583;');

	$form->addRule('username', 'range:5:20', 'Enter your username, 5 - 20 characters.');
	$form->addRule('password', 'range:5:20', 'Enter your password, 5 - 20 characters.');

	$form->addFilter('_ALL_', 'db');

$form->display();

?></td>
		<td width="148">my menu</td>
	</tr>
</table>

</body>

</html>
<?}?>

original code:

Code: Select all

<?	require_once 'global.php'; ?><html>

<head>
<meta http-equiv="Content-Language" content="fa">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>left menu</title>
</head>

<body>

<table border="1" width="100%" id="table1" height="346">
	<tr>
		<td width="97" height="37">left menu</td>
		<td height="37">
		<p align="center">I'd like items here</td>
		<td width="148" height="37">right menu</td>
	</tr>
	<tr>
		<td width="97">my menu</td>
		<td><?php
   
/* $Id: login.php,v 1.7 2002/09/03 22:02:01 shaggy Exp $ */




	require_once 'html_form.php';
	$form = new Form(uri_self());

	$form->addText('username', '&#1588;&#1606;&#1575;&#1587;&#1607; &#1603;&#1575;&#1585;&#1576;&#1585;&#1610;');
	$form->addPassword('password', '&#1585;&#1605;&#1586; &#1593;&#1576;&#1608;&#1585;');
	$form->addCheckbox('remember', 'Remember me');

	$form->addSubmit('&#1608;&#1585;&#1608;&#1583;');

	$form->addRule('username', 'range:5:20', 'Enter your username, 5 - 20 characters.');
	$form->addRule('password', 'range:5:20', 'Enter your password, 5 - 20 characters.');

	$form->addFilter('_ALL_', 'db');

	if ($form->valid()) {
		$processed = $form->getProcessed();
		$remember = $form->getValue('remember');

		if (!isset($_SESSION['login'])) {
			$_SESSION['login'] = 3;
		} else {
			if ($_SESSION['login'] <= 1) {
				die('You cannot log in.');
			}
		}

		if ($user->_checkLogin($processed['username'], $processed['password'], $remember)) {
			if (isset($_SESSION['log_to'])) {
				redirect($_SESSION['log_to']);
			} else {
				redirect('account.php/');
			}
		} else {
			failed($form);
		}

	} else {
		begin_html();
		$form->display();
	}

	function failed(&$form) {
		begin_html();
		echo "<p>You could not be logged in, $_SESSION[login] attempts left.</p>
		<p>Possible reasons for this are:</p>

		<ul>
			<li>Your username and/or password is not correct.
				Check your username and password and then try again.</li>
			<li>You haven't " .
			'<a href="signup.php" title="Sign up for an account, it is free">registered</a> yet</li>
			<li>Your account is temporarily disabled.</li>
			<li>You are trying to login simultaneously from two different computers or
			two browsers on the same computer.</li>
		</ul>';

		$form->display();
	}

?></td>
		<td width="148">my menu</td>
	</tr>
</table>

</body>

</html>

Posted: Mon Jul 02, 2007 3:54 pm
by volka
please try

Code: Select all

<?php
include('global.php');
include('html_form.php');

if ( !isset($form) ) {
	echo '<div>there is no $form</div>';
	die();
}
else if ( !is_object($form) ) {
	echo '<div>$form is not an object but a ', gettype($form), '</div>';
	die();
}
if ($form->valid()) {

Posted: Mon Jul 02, 2007 3:57 pm
by m2babaey
thanks :wink:
result:
there is no $form

Posted: Mon Jul 02, 2007 3:58 pm
by volka
Then neither global.php nor html_form.php define a global variable $form.

Posted: Mon Jul 02, 2007 3:58 pm
by RobertGonzalez
Why didn't you just fix the header handling?

Posted: Mon Jul 02, 2007 4:03 pm
by m2babaey
Why didn't you just fix the header handling?
I have not been able to do so yet.
maybe if I add another "if" statement to the login code and let the action be php-self, it solves the problem but i couldn't decide how to add the if.
Then neither global.php nor html_form.php define a global variable $form.
this is what html_form is doing:

Code: Select all

class Form {

	var $_method = 'post';
	var $_action = '';
	var $_elements = array();
	var $_vars = null;
	var $_processed = array();
	var $_rules = array();
	var $_js = '';
	var $_filters = array();
	var $required = '<strong>*</strong>';
	var $_message = '';

	var $table_attr = Array(
		'cellpadding' => '0',
		'cellspacing' => '8',
		'summary' => 'form handler'
	);
plus other functions

Posted: Mon Jul 02, 2007 4:13 pm
by RobertGonzalez
Somewhere along the line the variable $form needs to be set to the object.

Posted: Mon Jul 02, 2007 4:15 pm
by volka
That's the class Form. But where is the variable $form set?

I think your problems all are based on the fact that you haven't understood the lifcycle of a http request/php instance but I don't have the time for that subject right now. Maybe tomorrow.

Posted: Mon Jul 02, 2007 4:15 pm
by superdezign
A class and an object are not the same.

Edit: Everyone beat me to it.

Posted: Mon Jul 02, 2007 10:08 pm
by m2babaey
I have something like this on my first post. (second code):

Code: Select all

require_once 'html_form.php';
        define("act","loginaction.php");
        $form = new Form(act);
and then the form elements. isn't that enough?
That has appeared different :? $form and new are red in the code
:roll:

Posted: Tue Jul 03, 2007 5:34 am
by volka
Let's assume you have three files.

Code: Select all

<?php // header.php
$start = microtime(true);
echo '<html>
	<head>
		<title>...</title>
	</head>
	<body>
		<pre>_POST:', print_r($_POST, true), '</pre>';
?>

Code: Select all

<?php // footer.php
echo '
		<p>', microtime(true) - $start, '</p>
	</body>
</html>';
?>

Code: Select all

<?php // test.php
require 'header.php';

echo '
		<form method="post" action="?">
			<div>
				<input type="text" name="foo" />
				<input type="submit" />
			</div>
		</form>';

require 'footer.php';
?>
Now you type the url of test.php in your browser's location bar. The browser sends a http request to the webserver and the webserver decides that php should handle this request. The webserver creates a new instance of php and passes the path of test.php to it. The php instance parses test.php and starts to execute it. When it reaches the require 'header.php' it loads and parse header.php (still the same php instance) and then executes this script. When the header.php is done the php instance continues with test.php and reaches require 'footer.php';. footer.php is loaded, parsed and executed (still in the same php instance). header.php defined a variable $start and since footer.php is executed in the same php instance this variable is still valid here. When footer.php is done php again continues with test.php. There's nothing else in test.php. The request is handled, all output from the php instance is sent to the client as http response and then the php instance is removed instantaniously - including all variables, resources, etc of that instance.
The client receives the http response and in this case renderes the html document including the html form. If you open then browser's source view you can see what the browser received as response for the last request (except the http headers). You will find no php code in there because the browser only received the output of the php instance.
Unless your webserver is really, really slow there is no active php instance while the user enters something into the input/text element of the form. That's completely client-side, you could shut the webserver down now and the user would still be able to use the html form.
But when you submit the form the browser sends a new http request and the webserver creates a new instance of php. This new instance again parses test.php and start executing it. There's no variable $start until the execution reaches require 'header.php' and $start = microtime(true); in header.php again because it's a completely new instance of php that is not connected to the previous instance in any way.
header/location adds a http header to the response that advices the browser to request another document immediately. The browser sends a new http request with the url given in the location header. new http request, new php instance, all variables of the old instance gone.
I hope this was somehow comprehensible...

Posted: Tue Jul 03, 2007 7:05 am
by m2babaey
many thanks for your help :P
especially to vplka that put a lot of time to type that all comments
problem got solved