Here is a code:
public function loginAction()
{
$form = new Application_Form_Login();
$this->view->form = $form;
if($this->_request->isPost())
{
self::$dataForm = $this->_request->getPost();
if($this->form->isValid(self::$dataForm))
{
return $this->_forward('authorization');
} else
{
$this->form->populate(self::$form);
}
}
}
public function authorizationAction()
{
if($this->_request->isPost())
{
$auth = Zend_Auth::getInstance();
$authAdapter = new Application_Model_User($this->user->getAdapter(),'user');
$authAdapter->setIdentityColumn('USERNAME')
->setCredentialColumn('PASSWORD');
$password = md5(self::$dataForm['password']);
$authAdapter->setIdentity(self::$dataForm['username']);
$authAdapter->setCredental($password);
$result = $auth->authenticate($authAdapter);
echo 'ok';
/*
if($result->isValid())
{
//$this->_forward('authorized', 'user');
echo 'ok';
}*/
}
}
Any idea why it does not work? I didn't get any error just blank page.
Shouldn't you be calling if($form->isValid(self::$dataForm)) ?
As far as I understand it is a bad idea to use the $this->_forward() as it calls the dispatch loop again.
Personally I would place the authorization code into a model class and pass it the username & password from the form.
Related
I am new to php and I am trying to program an app that uses php as backend. I don't really have an error in my code but I can't figure something out I have search but nothing has helped.there maybe be a solution but I can't find it.
I have 3 php file
Index.php
<?php
include "methods.php";
$user=new user();
if (isset($_GET["action"])) {
// code...
switch ($_GET["action"]) {
case 'login':
// code...
$user->login();
break;
default:
// code...
echo("error 404");
break;
}
} else {
// code...
echo("error 404");
}
?>
Methods.php
<?php
include "extra.php";
class user {
public function login() {
$input = new input();
$error = "fucked";
$validationresult = json_decode($input->validateinput(), true);
echo var_dump($validationresult);
$validated = $validationresult["validated"];
if ($validated) {
// code...
echo ("yes");
} else {
echo var_dump($validationresult);
// echo json_encode(($validationresult["error"]));
}
}
}
?>
extra.php
<?php
class input {
public $password;
public $status;
public $validated;
public function __construct()
{
// code...
}
public function validateinput () {
$password = $_GET["password"];
$this-> $status = "red";
$this->$validated = false;
echo($this-> $status);
return json_encode('{
"validated":'.$this->get_validate().',
"error":{
"status":"'.$this->$status.'",
"username":"ok",
"password":"cannot be more than 5"
}
}');
}
public function get_validate(){
return $this->$validated;
}
}
?>
As you can see in index.php I called $user->login();
From methods.php which echos JSON $input->validateinput() from file extra.php.
But
"validated":'.$this->get_validate().'
And
"status":"'.$this->$status.'
From extra.php
Is empty
I don't why it is empty and the internet confuses me more.
I am sorry for my grammatical mistakes as I am typing from a mobile phone and English isn't my first language.
I'm new to PHP. I'll like to check the scope of the variables I've used. In particular $model.
$model = new LoginModel();
$controller = new LoginController($model);
$view = new LoginView($controller, $model);
Attached below are codes I have written for logging in. A user would visit the page via GET /login.php then submits the form to POST /login.php?action=login. In this process the LoginModel is updated accordingly by LoginController.
I would like to use the $model that I have updated in later parts of the execution of the page. However, I noticed that $model is "reset" once the call returns from LoginController.login().
I'm not sure if it is because $model was passed by value in my case. Or if there is something else I'm doing wrong but I'm not aware of. Can anyone enlighten me on this?
<?php
class LoginModel {
public $username = "";
public $password = "";
public $message = "";
public $loginSuccess = false;
public function __construct() {
}
}
class LoginView {
private $model;
private $controller;
public function __construct($controller, $model) {
$this->controller = $controller;
$this->model = $model;
}
public function getUsernameField() {
return $this->makeInput("text", "username", "");
}
public function getPasswordField() {
return $this->makeInput("password", "password", "");
}
private function makeInput($type, $name, $value) {
$html = "<input type=\"$type\" name=\"$name\" value=\"$value\" />";
return $html;
}
}
class LoginController {
const HOME_URL = "http://localhost/";
private $model;
public function __construct($model) {
$this->model = $model;
}
public function login() {
$username = $_POST['username'];
$password = $_POST['password'];
if ($username === $password) {
$_SESSION['username'] = $username;
$model->username = $username;
$model->password = "";
$model->message = "Hello, $username!";
$model->loginSuccess = true;
header("Refresh: 3; URL=" + LoginController::HOME_URL);
} else {
$model->message = "Sorry, you have entered an invalid username-password pair.";
$model->loginSuccess = false;
}
}
public function handleHttpPost() {
if (isset($_GET['action'])) {
if ($_GET['action'] === 'login') {
$this->login();
}
} else {
// invalid request.
http_response_code(400);
die();
}
}
public function handleHttpGet() {
if (isset($_GET['action'])) {
// request for controller action
// No controller actions for HTTP GET
} else {
// display login page
}
}
public function redirectToHome() {
header("Location: " + LoginController::HOME_URL);
die();
}
}
$model = new LoginModel();
$controller = new LoginController($model);
$view = new LoginView($controller, $model);
if (isset($_SESSION['username'])) {
$controller->redirectToHome();
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$controller->handleHttpPost();
} else if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$controller->handleHttpGet();
}
?>
<html>
<body>
<?php if ($model->loginSuccess) { ?>
<h1>Login Successful, Redirecting...</h1>
<p><?= $model->message; ?></p>
<?php
} else { ?>
<form action="login.php?action=login" method="POST">
Username: <br />
<?php echo $view->getUsernameField(); ?> <br/><br/>
Password: <br />
<?php echo $view->getPasswordField(); ?><br/><br/>
<input type="submit" value="Log In"/>
</form>
<p><?= $model->message; ?></p>
<?php
}?>
</body>
</html>
Update: Solved. Thanks #RiggsFolly for pointing it out.
Well, I got the wrong$model.
public function login() {
....
$model->username = $username; //referenced the wrong variable
$this->model->username = $username //should have done this.
}
Also, Thanks #Fred -ii-
(sorry I left you out)
public function login() {
....
header("Refresh: 3; URL=" + LoginController::HOME_URL); //not the right way to concat
header("Refresh: 3; URL=" . LoginController::HOME_URL); //should have been this.
}
Only a simple statement
for because $model was passed by value
We have an object in $model and pass it to the constructor
$controller = new LoginController($model);
it will be bound as reference to
$controller->model = $model.
Now we have an reference of the model in the controller.
If you know do (if possible, lets say yes) this: unset($controller->model);
you dont have killed the $model instance, you have just removed the reference to $model that was set before.
But now the other way around:
#create an object
$model = new stdClass();
#create the holder
$b=new stdClass();
#bind the first obj
$b->model=$model;
#unset the first object
$model=null;
unset($model);
#oooh, what it is still there
print_r($b->model);
Here we have not unset($model) for real, because php knows that the instance is used later. So php goes and kills the reference between $model and the real object, but not the reference between $b->model and the real object.
In a way the reference has moved vom one ref-pointer to the next.
Last thing about
By default, function arguments are passed by value (so that if the value of the argument within the function is changed, it does not get changed outside of the function).
that comes from php documentaion.
When here is written passed by value it means, how it will work.
But in the real process, it will copied in the moment when it is manipulated.
so it is passed by ref but act like passed by value and only objects will be always an reference until clone.
To keep the most important Infos in this answer:
For one thing, header("Refresh: 3; URL=" + LoginController::HOME_URL);
you're trying to concatenate with a + which in PHP it's a dot that
needs to be used. You seem to be coming from a C background, hence the
error.
Thanks to Fred -ii-
I would like to know that if there is a method in the controller which require arguments and the user changes the argument in the URL by hand, and presses enter it should display the default page. Below is my bootstrap, then I have already created a error controller for URL error. So please give some coding guide or if there is some thing in my code, change it. Thanks in advance.
<?php
class App
{
protected $controller = 'indexController';
protected $method = 'index';
protected $params = array();
public function __construct()
{
$url = $this->parseUrl();
//print_r($url);
if (isset($url[0]))
{
if (file_exists('app/controllers/'.$url[0].'.php'))
{
$this->controller = $url[0];
unset($url[0]);
}
require_once('app/controllers/'.$this->controller.'.php');
$this->controller = new $this->controller;
}
else
{
$error = new errorController();
$error->setError("Page Not Found");
echo $error->getError();
}
if (isset($url[1]))
{
if (method_exists($this->controller,$url[1]))
{
$this->method = $url[1];
unset($url[1]);
}
else
{
$error = new errorController();
$error->setError("Page Not Found");
echo $error->getError();
}
}
else
{
$error = new errorController();
$error->setError("Page Not Found");
echo $error->getError();
}
$this->params = $url ? array_values($url) : array();
call_user_func_array(array($this->controller,$this->method),$this->params);
}
public function parseUrl()
{
if (isset($_GET['url']))
{
return $url =explode('/',filter_var(rtrim($_GET['url'],'/'),FILTER_SANITIZE_URL));
}
}
}
The method itself must check if the parameters provided are valid and throw an exception if not. Afterwards just catch the exception and trigger and error page to be displayed.
Seems like you could use POST and $_POST, instead of GET. Then it won't matter if the user includes or alters parameters because your PHP will ignore them.
I'm trying to pass multiple parameters in a url that looks like this...
http://somedomain.com/lessons/lessondetails/5/3
... to a function in the controller that looks like this ...
class LessonsController extends Controller
{
public function lessonDetails($studentId, $editRow=NULL)
{
try {
$studentData = new StudentsModel();
$student = $studentData->getStudentById((int)$studentId);
$lessons = $studentData->getLessonsByStudentId((int)$studentId);
if ($lessons)
{
$this->_view->set('lessons', $lessons);
}
else
{
$this->_view->set('noLessons', 'There are no lessons currently scheduled.');
}
$this->_view->set('title', $student['first_name']);
$this->_view->set('student', $student);
return $this->_view->output();
} catch (Exception $e) {
echo "Application error: " . $e->getMessage();
}
}
}
But only the first parameter seems to pass successfully.
Not sure what to copy and paste here but here's the bootstrap.php...
$controller = "students";
$action = "index";
$query = null;
if (isset($_GET['load']))
{
$params = array();
$params = explode("/", $_GET['load']);
$controller = ucwords($params[0]);
if (isset($params[1]) && !empty($params[1]))
{
$action = $params[1];
}
if (isset($params[2]) && !empty($params[2]))
{
$query = $params[2];
}
}
$modelName = $controller;
$controller .= 'Controller';
$load = new $controller($modelName, $action);
if (method_exists($load, $action))
{
$load->{$action}($query);
}
else
{
die('Invalid method. Please check the URL.');
}
Thanks in advance!
Call $this->getRequest()->getParams() from your action controller and check if both parameters are there.
If NO, the problem lies with your routing.
If YES, the problem lies with passing the parameters to your controller method lessonDetails.
Also, lessondetailsAction is missing. (this will be the method called if you visit the url you posted)
The question is simple:
How can i pass data from model to view(or back to the controller) to display errors like "your password is too short"
Here is the controller
class UsersController extends Controller {
private $username;
private $password;
function register()
{
if($_POST)
{
$this->User->username = $_POST['username'];
$this->User->password = $_POST['password'];
$this->User->register();
}
}
}
the model
class User extends Model {
public $username;
public $password;
function register()
{
$username = $this->username;
$password = $this->password;
if (!empty($username) && !empty($password))
{
// registration process
}
else
{
// "you must provide a username and password" or something like that
}
}
Just have your register function in your model return "PASSWORD"; to the controller and have your controller take the return from the model and return it to the view. Let the view interpret what the error output for "PASSWORD" is.
Example:
the controller
class UsersController extends Controller {
private $username;
private $password;
function register()
{
if($_POST)
{
$this->User->username = $_POST['username'];
$this->User->password = $_POST['password'];
return $this->User->register();
}
}
}
the model
class User extends Model {
public $username;
public $password;
function register()
{
$username = $this->username;
$password = $this->password;
if (!empty($username) && !empty($password))
{
// ...
return "SUCCESS";
}
else
{
return "PASSWORD";
}
}
}
the view
$responses = array("SUCCESS" => "Registered Successfully!", "PASSWORD" => "You must provide a username and password!");
$result = $this->UsersController->register();
echo $responses[$result];
Simply have your model methods to return a value, or throw exceptions, like any normal method. Then handle it in the controller. The view shouldn't touch the data directly from the model, that's the controller's job.
public function addAction()
{
$form = $this->_getForm();
$this->view->form = $form;
$this->render('add', null, true);
}
public function editAction()
{
$id = $this->getRequest()->getParam(0);
$Model = DI::get('yourclass_Model');
$form = $this->_getForm();
$data = $Model->getData();
$form->populate($data);
$this->view->flashMessages = $this->_helper->FlashMessenger->getMessages();
$this->view->form = $form;
$this->render('add', null, true);
}
public function saveAction()
{
$form = $this->_getForm();
$Model = DI::get('yourclass_Model');
try{
$saved = $Model->saveForm($form, $_POST);
} catch (Exception $e) {
echo "<pre>";
print_r($e);
exit;
}
if($saved)
{
$this->_helper->FlashMessenger('Record Saved!');
$this->_redirect("edit".$form->id->getValue(), array('exit'=>true));
}
$this->view->errorMessage = 'There were some errors';
$this->view->form = $form;
$this->render('add', null, true);
}
Create a class which implements Singleton pattern and ArrayAccess interface.
Or create something similar with dependency injection.
The ultimate solution would be if you create some validation architecture. (The model validates its self and it's error state is available in the views.)