PHP - What is wrong? Learning MVC - Beginner - php

Hy,
i started learning PHP and i created a simple MVC Style Codebase.
The Script just generates a random number and displays this numer. I also write a function to display the number shown before but it does not work. The value is empty. Can you help me out, i have no clue whats wrong and there is no php error thrown.
view.php
<?php
class View
{
private $model;
private $view;
public function __construct()
{
$this->model = new Model();
}
public function output()
{
echo 'Current Entry: ';
echo $this->model->getData();
echo '<br />';
echo 'Update';
echo '<br />';
echo 'Last';
}
public function getModel()
{
return $this->model;
}
}
controller.php
<?php
class Controller
{
private $model;
private $view;
public function __construct($view)
{
$this->view = $view;
$this->model = $this->view->getModel();
}
public function get($request)
{
if (isset($request['action']))
{
if ($request['action'] === 'update')
{
for ($i = 0; $i<6; $i++)
{
$a .= mt_rand(0,9);
}
$this->model->setData($a);
}
elseif ($request['action'] === 'preview')
{
$this->model->setLast();
}
else
{
$this->model->setData('Wrong Action');
}
}
else
{
$this->model->setData('Bad Request');
}
}
}
model.php
<?php
class Model
{
private $data;
private $last;
public function __construct()
{
$this->data = 'Default';
}
public function setData($set)
{
if ( ! (($set == 'Wrong Action') && ($set == 'Bad Request')))
{
$this->last = $this->data;
}
$this->data = $set;
}
public function getData()
{
return $this->data;
}
public function setLast()
{
$this->data = $this->last;
}
public function getLast()
{
return $this->last;
}
}
index.php
<?php
require_once 'controller.php';
require_once 'view.php';
require_once 'model.php';
$view = new View();
$controller = new Controller($view);
if (isset($_GET) && !empty($_GET)) {
$controller->get($_GET);
}
$view->output();
Are there any other, bad mistakes in the Script?
Any input very welcome! :)

The problem with your code is that PHP does not preserve variable values between requests, therefore, when you set your $model->last value here:
$this->last = $this->data;
It gets reset on your next request.
You may want to store $last value in a session or a cookie instead. Something like:
$_SESSION['last'] = $this->data;
And then when you are instantiating your model you could initialize it with a value stored in a session if available:
index.php - add session_start() at the beginning
model.php:
public function __construct()
{
$this->data = isset($_SESSION['last']) ? $_SESSION['last'] : 'Default';
}
public function setData($set)
{
$this->data = $set;
if ( ! (($set == 'Wrong Action') && ($set == 'Bad Request')))
{
$_SESSION['last'] = $this->data;
}
}
controller.php
elseif ($request['action'] === 'preview')
{
//Remove this
//$this->model->setLast();
}

Related

PHP - Json is empty after converting object

So basically I want to have an Object Class with a bunch of setters that I can manipulate and then convert straight to JSON. In the past I was using an already existing JSON as model(json->object->json). Now I want to just have object->json.
But at the moment I get an empty array when I try to use json_encode.
Also had some trouble with my $index that I'm using because I can have multiple numerical indexes inside "items"
PHP:
<?php
namespace ProjectApi\Models;
use ArrayObject;
use stdClass;
class MagentoInvoice
{
public $capture = true;
public $notify = true;
public function __construct()
{
}
public function setCapture($capture)
{
$this->capture = $capture;
}
public function getCapture()
{
return $this->capture;
}
public function setNotify($notify)
{
$this->notify = $notify;
}
public function getNotify()
{
return $this->notify;
}
public function setItems($itemsCount)
{
$i = 0;
while($i < $itemsCount)
{
$this->items = new stdClass();
$i++;
}
}
public function getItems()
{
return $this->items;
}
public function setProductQty($index, $qty)
{
$this->items->$index->qty = $qty;
}
public function getProductQty($index)
{
return $this->items->$index->qty;
}
public function setProductOrderItemId($index, $id)
{
$this->items->$index->order_item_id = $id;
}
public function getProductOrderItemId($index)
{
return $this->items->$index->order_item_id;
}
}
JSON
{"capture":true,"items":[{"order_item_id":123,"qty":1},{"order_item_id":321,"qty":1}],"notify":true}
$body = new MagentoInvoice();
$body->setCapture(true);
$body->setNotify(true);
if($firstProductId != null && $secondProductId != null)
{
$body->setItems(2);
$body->setProductQty(0, 1);
$body->setProductOrderItemId(0, $firstProductId);
$body->setProductQty(1, 1);
$body->setProductOrderItemId(1, $secondProductId);
}
print_r(json_encode($body));

variable won't change in PHP class

The method -- initially called in index.php -- redirects to another page. The problem here is that variable $logged_in isn't getting assigned a new value... which means that when the variable is used in the other page, it is read as false.
NOTE: The assignment of session 'id' and session 'type' is correct.
class Session {
public $logged_in = false;
public function login($data) {
if ($data) {
$_SESSION['id'] = $data['id'];
$_SESSION['type'] = $data['type'];
$this->logged_in = true;
}
}
}
This is a class and therefore is lost (its properties are lost) at the end of the first scripts execution and then recreated in the second in its initial state.
Classes do not live across executions of the same script or any other script.
If you wish to maintain the objects state, you will have to save the state to a file or maybe the real SESSION so you can re-hydrate the data when the second script starts
session_start();
class Session {
public function login($data) {
if ($data) {
$_SESSION['id'] = $data['id'];
$_SESSION['type'] = $data['type'];
$_SESSION['logged_in'] = true;
}
}
// getter function
public function is_logged_in()
{
// just in case check
if ( isset($_SESSION['logged_in']) ) {
return $_SESSION['logged_in'] == true;
} else {
return false;
}
}
}
Called like this
$s = new Session();
if ( ! $s->is_logged_in() ) {
header('Location: index.php');
exit;
}
To keep it away from the SESSION completely you could
class Session {
public $id;
public $type;
public $logged_in;
public function __construct()
{
if ( file_exists('my_session.txt')) {
$obj = json_decode(file_get_contents('my_session.txt'));
foreach($obj as $prop => $val) {
$this->{$prop} = $val;
}
}
}
public function __destruct()
{
file_put_contents('my_session.txt', json_encode($this));
}
public function login($data) {
if ($data) {
$this->id = $data['id'];
$this->type = $data['type'];
$this->logged_in = true;
}
}
}
$obj = new Session();
$obj->login(array('id'=>99, 'type'=>'TEST'));
print_r($obj);
$obj = null;
echo 'object nulled' . PHP_EOL;
print_r($obj);
echo ' NOTHING should be printed' . PHP_EOL;
echo 'object rehydrated' . PHP_EOL;
$obj = new Session();
print_r($obj);
create another method check_login() to re-assign the values in the new page and call it within __construct()
function __construct(){
$this->check_login();
}
public function check_login(){
if(isset($_SESSION['id']) && isset($_SESSION['type']){
$this->logged_in = true;
} else {
$this->logged_in = false;
}
}

Get data return php oop

getclass.php
public $set;
//dont need to care here the code is right , here is where it final result
default;
$this->actual_device = "desktop";
echo $this->issetValueNull($this->actual_device);
public function issetValueNull($mixed)
{
$this->set = $mixed;
}
getdata.php
require_once "getclass.php";
$check_detect_device = new detect_device();
if($check_detect_device->issetValueNull->set1 = "desktop"){
"<script>console.log('desktop');</script>";
}
i need to get the data from getclass.php to getdata.php and check the final result at getdata.php , some like below;
//this data return from getclass.php
if(isset($_GET['desktop'])){
"<script>console.log('desktop');</script>";
}
but i dont know how to return the data from getclass , can any one give me some advice ?
Im not sure is this what you are trying to do, but check my example:
<?php
class getClass
{
public $actualDevice;
public function __construct()
{
$this->actualDevice = "desktop";
}
public function setActualDevice($actualDevice)
{
$this->actualDevice = $actualDevice;
return $this;
}
public function getActualDevice()
{
return $this->actualDevice;
}
public function issetActualDevice()
{
return isset($this->actualDevice);
}
}
class getData
{
public $getClass;
public function __construct(getClass $getClass)
{
$this->getClass = $getClass;
}
public function checkDetectDevice($device)
{
if ($this->getClass->getActualDevice() == $device) {
return true;
}
return false;
}
}
$getClass = new getClass();
$getData = new getData($getClass);
if ($getData->checkDetectDevice($_GET['desktop'])) {
echo "<script>console.log('desktop');</script>";
}

php Fatal error: Class '' not found in..doesnt specify the class

I'm getting a class not found error but without the name of the class. I got the code from here
but when I try to run it, it gives the following error..
Fatal error: Class '' not found in C:\Program Files\Apache Software Foundation\Apache24\Apache24\htdocs\framework\library\controller.class.php on line 16
and the following is the controller
<?php
class Controller {
protected $_model;
protected $_controller;
protected $_action;
protected $_template;
function __construct($model, $controller, $action) {
$this->_controller = $controller;
$this->_action = $action;
$this->_model = $model;
include 'model.class.php';//other similar posts suggested this but its not working
$this->$model = new $model;
$this->_template = new Template($controller,$action);
}
function set($name,$value) {
$this->_template->set($name,$value);
}
function __destruct() {
$this->_template->render();
}
}
I'm assuming its the model class which is not being found. The model class code is
<?php
class Model extends SQLQuery {
protected $_model;
function __construct() {
$this->connect(DB_HOST,DB_USER,DB_PASSWORD,DB_NAME);
$this->_model = get_class($this);
$this->_table = strtolower($this->_model)."s";
}
function __destruct() {
}
}
and sqlquery class is
<?php
class SQLQuery {
protected $_dbHandle;
protected $_result;
/** Connects to database **/
function connect($address, $account, $pwd, $name) {
$this->_dbHandle = #mysql_connect($address, $account, $pwd);
if ($this->_dbHandle != 0) {
if (mysql_select_db($name, $this->_dbHandle)) {
return 1;
}
else {
return 0;
}
}
else {
return 0;
}
}
/** Disconnects from database **/
function disconnect() {
if (#mysql_close($this->_dbHandle) != 0) {
return 1;
} else {
return 0;
}
}
function selectAll() {
$query = 'select * from `'.$this->_table.'`';
return $this->query($query);
}
function select($id) {
$query = 'select * from `'.$this->_table.'` where `id` = \''.mysql_real_escape_string($id).'\'';
return $this->query($query, 1);
}
/** Custom SQL Query **/
function query($query, $singleResult = 0) {
$this->_result = mysql_query($query, $this->_dbHandle);
if (preg_match("/select/i",$query)) {
$result = array();
$table = array();
$field = array();
$tempResults = array();
$numOfFields = mysql_num_fields($this->_result);
for ($i = 0; $i < $numOfFields; ++$i) {
array_push($table,mysql_field_table($this->_result, $i));
array_push($field,mysql_field_name($this->_result, $i));
}
while ($row = mysql_fetch_row($this->_result)) {
for ($i = 0;$i < $numOfFields; ++$i) {
$table[$i] = trim(ucfirst($table[$i]),"s");
$tempResults[$table[$i]][$field[$i]] = $row[$i];
}
if ($singleResult == 1) {
mysql_free_result($this->_result);
return $tempResults;
}
array_push($result,$tempResults);
}
mysql_free_result($this->_result);
return($result);
}
}
/** Get number of rows **/
function getNumRows() {
return mysql_num_rows($this->_result);
}
/** Free resources allocated by a query **/
function freeResult() {
mysql_free_result($this->_result);
}
/** Get error string **/
function getError() {
return mysql_error($this->_dbHandle);
}
}
I'm new to PHP and I'm using PHP 5.5.15. I know I should probably switch this to pdo, but i just want to get this working before gettin jiggy with it.
Any help much appreciated
Simple said, you have this function for your controller:
function __construct($model, $controller, $action) {
$this->$model = new $model;
}
You need to give a $model, wich would be the name of a class. You give no name. This is why class "" can not be found.
If we would write this:
$controller = new Controller("mycrazymodel", null, null);
It means:
function __construct($model, $controller, $action) {
//$this->$model = new $model;
$this->$model = new mycrazymodel; //above means this, if $model = "mycrazymodel"
}
So what does this mean for you?
Locate the call of the Controller::__construct method, which typical mean new Controller(...) and make sure, you give the classname as $model parameter.
Take a look at the manual for further information: http://php.net/manual/en/language.namespaces.dynamic.php

Running class methods in cascade

I have a system that was designed to do a kind of cascading - get the sequence of methods called upon success of the previous condition.
The example is the below code, which I presume it's not a best practice for doing this, so would be great if I could get some suggestions to refactor this, probably using a design pattern or a different than this system.
<?php
class Model
{
public function isOk()
{
return true;
}
}
class OtherClass
{
public function isOk()
{
return true;
}
}
class AnotherClass
{
public function verifies()
{
return true;
}
}
class Sequence
{
public function fire()
{
$model = new Model();
if($model->isOk()) {
$otherclass = new OtherClass();
if($otherclass->isOk()) {
$anotherclass = new AnotherClass();
if($anotherclass->verifies()) {
echo "We're done with the sequence.";
return true;
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
}
}
$sequence = new Sequence();
echo $sequence->fire();
?>
I would avoid deep nesting of if/else statements to enhance the readability. One way is to use early return:
class Test1
{
public function isOk()
{
echo 'Test1';
return true;
}
}
class Test2
{
public function isOk()
{
echo 'Test2';
return true;
}
}
class Sequence
{
public function fire()
{
$test1 = new Test1();
if (!$test1->isOk()) {
return false;
}
$test2 = new Test2();
if (!$test2->isOk()) {
return false;
}
echo "We're done with the sequence.";
return true;
}
}
If you need it more dynamically you could use call_user_func or call_user_func_array.
class Sequence
{
protected $sequence = array(
array('Test1', 'isOk'),
array('Test2', 'isOk'),
);
public function fire()
{
foreach ($this->sequence as $callback) {
if (!call_user_func(array(new $callback[0], $callback[1]))) {
return false;
}
}
echo "We're done with the sequence.";
return true;
}
}

Categories