I got this error message:
PHP Fatal error: Call to a member function get() on null in /home/key2demo/domains/key2datafeed.com/public_html/ocdemoshops/oc23/system/engine/controller.php on line 10
All the code in the controller is:
<?php
abstract class Controller {
protected $registry;
public function __construct($registry) {
$this->registry = $registry;
}
public function __get($key) {
return $this->registry->get($key);
}
public function __set($key, $value) {
$this->registry->set($key, $value);
}
}
The code i use registry in is this:
define("VERSION", "1.0");
define("LANGUAGE", "1");
if (is_file('./../admin/config.php')) {
require_once('./../admin/config.php');
}
require_once(DIR_SYSTEM . 'startup.php');
$application_config = 'admin';
$registry = new Registry();
$loader = new Loader($registry);
$registry->set('load', $loader);
$config = new Config();
$config->load('default');
$config->load($application_config);
$registry->set('config', $config);
$registry->set('request', new Request());
$response = new Response();
$response->addHeader('Content-Type: text/html; charset=utf-8');
$registry->set('response', $response);
$registry->set('cache', new Cache($config->get('cache_type'), $config-
>get('cache_expire')));
$registry->set('url', new Url($config->get('site_ssl')));
$language = new Language($config->get('language_default'));
$language->load($config->get('language_default'));
$registry->set('language', $language);
$registry->set('document', new Document());
$event = new Event($registry);
$registry->set('event', $event);
if ($config->get('db_autostart')) {
$registry->set('db', new DB($config->get('db_type'), $config-
>get('db_hostname'), $config->get('db_username'), $config-
>get('db_password'), $config->get('db_database'), $config-
>get('db_port')));
}
if ($config->get('session_autostart')) {
$session = new Session();
$session->start();
$registry->set('session', $session);
}
if ($config->has('action_event')) {
foreach ($config->get('action_event') as $key => $value) {
$event->register($key, new Action($value));
}
}
if ($config->has('config_autoload')) {
foreach ($config->get('config_autoload') as $value) {
$loader->config($value);
}
}
if ($config->has('language_autoload')) {
foreach ($config->get('language_autoload') as $value) {
$loader->language($value);
}
}
if ($config->has('library_autoload')) {
foreach ($config->get('library_autoload') as $value) {
$loader->library($value);
}
}
if ($config->has('model_autoload')) {
foreach ($config->get('model_autoload') as $value) {
$loader->model($value);
}
}
class K2P_API_OCWRITER extends Controller
{
private $errors;
private $admin;
private $adminValidated;
private $adminShops;
public function __construct()
{
$this->errors = array();
}
public function doLog($message)
{
file_put_contents('./key2_log.txt', $message, FILE_APPEND);
}
public function login($usr, $pwd)
{
if ($this->user->login($usr, $pwd)) {
return true;
$this->doLog('logged in');
} else {
$this->doLog('Failed to login, please supply a valid
username/password and check your webshop url');
die;
}
}
public function getLanguages()
{
}
}
$db = new DB(DB_DRIVER, DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
$registry->set('db', $db);
$registry->set('user', new Cart\User($registry));
$registry->set('tax', new Cart\Tax($registry));
$myAPI = new K2P_API_OCWRITER($registry);
$myAPI->config->set("config_language_id",LANGUAGE);
$command = $myAPI->cleanPost($_POST['command']);
$steps = $myAPI->cleanPost($_POST['steps']);
$page = $myAPI->cleanPost($_POST['page']);
$usr = $myAPI->cleanPost($_POST['usr']);
$pwd = $myAPI->cleanPost($_POST['pwd']);
//$myAPI->doLog(PHP_EOL . 'pages: ' . $page);
//$myAPI->doLog(PHP_EOL . 'steps: ' . $steps);
$totalProducts = $myAPI->getProductCount();
if ($myAPI->checkInput($usr,$pwd,$command,$page,$steps)) {
if ($myAPI->login($usr, $pwd)) {
switch($command){
case "getCategoryCount":
echo json_encode($myAPI->getCategoryCount(),JSON_FORCE_OBJECT
| JSON_UNESCAPED_SLASHES);
break;
case "getProductCount";
echo json_encode($myAPI->getProductCount(),JSON_FORCE_OBJECT |
JSON_UNESCAPED_SLASHES);
break;
case "getCategories":
echo json_encode($myAPI->getCategories($steps, $page,
JSON_FORCE_OBJECT | JSON_UNESCAPED_SLASHES));
break;
case "getProducts":
echo json_encode($myAPI->getProducts($steps, $page,
JSON_FORCE_OBJECT | JSON_UNESCAPED_SLASHES));
break;
default:
echo "Invalid command!";
break;
}
}
}
How can i fix it?
The error not in the abstract class. It's where you actually invoked the a property directly by calling $var->property1 since it's obviously the __get() magic method that's producing the error, which invokes the class get() method. Your controller's registry object needs to have the get() method. You probably don't have the correct registry obj passed into the controller constructor.
Related
I am making a web export from our program to OpenCart. I am trying to log in, but i get this error message:
PHP Fatal error: Call to a member function get() on null in /home/key2demo/domains/key2datafeed.com/public_html/ocdemoshops/oc23/system/engine/controller.php on line 10
We find out that the constructor in child class overwrites the one in parent. So parent constructor does not run and does not set this->registry.
The code in the controller is:
<?php
abstract class Controller {
protected $registry;
public function __construct($registry) {
$this->registry = $registry;
}
public function __get($key) {
return $this->registry->get($key);
}
public function __set($key, $value) {
$this->registry->set($key, $value);
}
}
This is The code i made:
define("VERSION", "1.0");
define("LANGUAGE", "1");
if (is_file('./../admin/config.php')) {
require_once('./../admin/config.php');
}
require_once(DIR_SYSTEM . 'startup.php');
$application_config = 'admin';
$registry = new Registry();
$loader = new Loader($registry);
$registry->set('load', $loader);
$config = new Config();
$config->load('default');
$config->load($application_config);
$registry->set('config', $config);
$registry->set('request', new Request());
$response = new Response();
$response->addHeader('Content-Type: text/html; charset=utf-8');
$registry->set('response', $response);
$registry->set('cache', new Cache($config->get('cache_type'), $config-
>get('cache_expire')));
$registry->set('url', new Url($config->get('site_ssl')));
$language = new Language($config->get('language_default'));
$language->load($config->get('language_default'));
$registry->set('language', $language);
$registry->set('document', new Document());
$event = new Event($registry);
$registry->set('event', $event);
if ($config->get('db_autostart')) {
$registry->set('db', new DB($config->get('db_type'), $config-
>get('db_hostname'), $config->get('db_username'), $config-
>get('db_password'), $config->get('db_database'), $config-
>get('db_port')));
}
if ($config->get('session_autostart')) {
$session = new Session();
$session->start();
$registry->set('session', $session);
}
if ($config->has('action_event')) {
foreach ($config->get('action_event') as $key => $value) {
$event->register($key, new Action($value));
}
}
if ($config->has('config_autoload')) {
foreach ($config->get('config_autoload') as $value) {
$loader->config($value);
}
}
if ($config->has('language_autoload')) {
foreach ($config->get('language_autoload') as $value) {
$loader->language($value);
}
}
if ($config->has('library_autoload')) {
foreach ($config->get('library_autoload') as $value) {
$loader->library($value);
}
}
if ($config->has('model_autoload')) {
foreach ($config->get('model_autoload') as $value) {
$loader->model($value);
}
}
class K2P_API_OCWRITER extends Controller
{
private $errors;
private $admin;
private $adminValidated;
private $adminShops;
public function __construct()
{
$this->errors = array();
}
public function doLog($message)
{
file_put_contents('./key2_log.txt', $message, FILE_APPEND);
}
public function login($usr, $pwd)
{
if ($this->user->login($usr, $pwd)) {
return true;
$this->doLog('logged in');
} else {
$this->doLog('Failed to login, please supply a valid
username/password and check your webshop url');
die;
}
}
public function getLanguages()
{
}
}
$db = new DB(DB_DRIVER, DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
$registry->set('db', $db);
$registry->set('user', new Cart\User($registry));
$registry->set('tax', new Cart\Tax($registry));
$myAPI = new K2P_API_OCWRITER($registry);
$myAPI->config->set("config_language_id",LANGUAGE);
$command = $myAPI->cleanPost($_POST['command']);
$steps = $myAPI->cleanPost($_POST['steps']);
$page = $myAPI->cleanPost($_POST['page']);
$usr = $myAPI->cleanPost($_POST['usr']);
$pwd = $myAPI->cleanPost($_POST['pwd']);
//$myAPI->doLog(PHP_EOL . 'pages: ' . $page);
//$myAPI->doLog(PHP_EOL . 'steps: ' . $steps);
$totalProducts = $myAPI->getProductCount();
if ($myAPI->checkInput($usr,$pwd,$command,$page,$steps)) {
if ($myAPI->login($usr, $pwd)) {
switch($command){
case "getCategoryCount":
echo json_encode($myAPI->getCategoryCount(),JSON_FORCE_OBJECT
| JSON_UNESCAPED_SLASHES);
break;
case "getProductCount";
echo json_encode($myAPI->getProductCount(),JSON_FORCE_OBJECT |
JSON_UNESCAPED_SLASHES);
break;
case "getCategories":
echo json_encode($myAPI->getCategories($steps, $page,
JSON_FORCE_OBJECT | JSON_UNESCAPED_SLASHES));
break;
case "getProducts":
echo json_encode($myAPI->getProducts($steps, $page,
JSON_FORCE_OBJECT | JSON_UNESCAPED_SLASHES));
break;
default:
echo "Invalid command!";
break;
}
}
}
If i add parent::__construct(); to it. It still don't work. I didn't know by which one I had to add it, so i tried both.
When i added parent::__construct(); to the controller like this:
<?php
abstract class Controller {
protected $registry;
public function __construct($registry) {
parent::__construct();
$this->registry = $registry;
}
public function __get($key) {
return $this->registry->get($key);
}
public function __set($key, $value) {
$this->registry->set($key, $value);
}
}
Then i get this error message:
PHP Fatal error: Call to a member function get() on null in /home/key2demo/domains/key2datafeed.com/public_html/ocdemoshops/oc23/system/engine/controller.php on line 11
And if i add it to my made code like this:
public function __construct()
{
parent::__construct();
$this->errors = array();
}
Then i get this error messages:
PHP Warning: Missing argument 1 for Controller::__construct(), called in /home/key2demo/domains/key2datafeed.com/public_html/ocdemoshops/oc23/key2publish/k2p_api_OCwriter.php on line 95 and defined in /home/key2demo/domains/key2datafeed.com/public_html/ocdemoshops/oc23/system/engine/controller.php on line 5
PHP Notice: Undefined variable: registry in /home/key2demo/domains/key2datafeed.com/public_html/ocdemoshops/oc23/system/engine/controller.php on line 6
PHP Fatal error: Call to a member function get() on null in /home/key2demo/domains/key2datafeed.com/public_html/ocdemoshops/oc23/system/engine/controller.php on line 10
Does anyone know how to fix this? I would like to hear.
Thanks!
Constructor of your Controller class takes $registry as argument. So when you call __construct of Controller class, you need to call it like:
parent::__construct($registry);
So, your constructor for K2P_API_OCWRITER which Controller can be:
class K2P_API_OCWRITER extends Controller
{
public function __construct($registry)
{
// pass `$registry` to parent `__construct`
parent::__construct($registry);
$this->errors = array();
}
}
And instantiating an object of K2P_API_OCWRITER is still:
$myAPI = new K2P_API_OCWRITER($registry);
And btw there's no need to write parent::__construct(); in Controller constructor, as it does not extend any classes, so it does not have parent.
I have this code:
class Service {
public function get_session($token) {
foreach ($this->config->sessions as $session) {
if ($token == $session->token) {
$session->last_access = date('r');
return $session;
}
}
return null;
}
public function mysql_connect($token, $host, $username, $password, $db) {
if (!$this->valid_token($token)) {
throw new Exception("Access Denied: Invalid Token");
}
// will throw exception if invalid
$this->mysql_create_connection($host, $username, $password, $db);
$session = $this->get_session($token);
$id = uniqid('res_');
if (!isset($session->mysql)) {
$session->mysql = new stdClass();
}
$mysql = &$session->mysql;
$mysql->$id = array(
'host' => $host,
'user' => $username,
'pass' => $password,
'name' => $db
);
return $id;
}
public function mysql_close($token, $res_id) {
if (!$this->valid_token($token)) {
throw new Exception("Access Denied: Invalid Token");
}
$session = $this->get_session($token);
if (!(isset($session->mysql->$res_id))) {
throw new Exception("Invalid resource id");
}
unset($session->mysql->$res_id);
if (empty((array)$session->mysql)) {
unset($session->mysql); // this don't work, don't know why
throw new Exception('isset($session->mysql) == ' .
(isset($session->mysql) ? 'true' : 'false'));
}
}
}
I call unset($session->mysql); if it's empty but the object is not removed, the exception throw true, How can I delete $session->mysql object? I've tried to add & in get_session but this didn't help.
Whole code can be found here.
You really should have posted your Session class in your post instead of linking to your GitHub repo... that's why the comments are confusing. You are using magic methods on your session class.
1 change I made: adding the magic __unset method.
Also, I had thought the constructor needed to be public but on further looking at it I was wrong about that (so my test code will not work unless the constructor is public... anyway...).
Here is the code below with the updated class:
<?
class Session {
public $storage;
public $token;
public $username;
public $browser;
public $start;
public $last_access;
private function __construct($u, $t, $s = null, $b = null, $d = null) {
$this->storage = $s ? $s : new stdClass();
$this->username = $u;
$this->token = $t;
$this->browser = $b ? $b : $_SERVER['HTTP_USER_AGENT'];
$this->start = $d ? $d : date('r');
}
function &__get($name) {
return $this->storage->$name;
}
function __set($name, $value) {
$this->storage->$name = $value;
}
function __isset($name) {
return isset($this->storage->$name);
}
function __unset($name) {
echo "Unsetting $name";
unset($this->storage->$name);
}
static function create_sessions($sessions) {
$result = array();
foreach ($sessions as $session) {
$result[] = new Session($session->username,
$session->token,
$session->storage,
$session->browser,
$session->start);
}
return $result;
}
static function cast($stdClass) {
$storage = $stdClass->storage ? $stdClass->storage : new stdClass();
return new Session($stdClass->username,
$stdClass->token,
$storage,
$stdClass->browser,
$stdClass->start);
}
static function new_session($username) {
return new Session($username, token());
}
}
And some test code:
$session = new Session('joe', '1234');
$session->mysql = 1234;
var_dump($session->mysql);
unset($session->mysql);
var_dump($session->mysql);
This is code of the added method:
function __unset($name) {
echo "Unsetting $name";
unset($this->storage->$name);
}
Check out the documentation to about the magic __unset method you need to add to your class:
http://php.net/manual/en/language.oop5.overloading.php#object.unset
__unset() is invoked when unset() is used on inaccessible properties.
There are few routers out there but I decided to create a very simple route for a very light site.
Here is my index.php
$route = new Route();
$route->add('/', 'Home');
$route->add('/about', 'About');
$route->add('/contact', 'Contact');
Here is my router:
<?php namespace Laws\Route;
use Laws\Controller\Home;
class Route
{
private $_uri = array();
private $_method = array();
private $_route;
public function __construct()
{
}
public function add($uri, $method = null)
{
$this->_uri[] = '/' . trim($uri, '/');
if ($method != null) {
$this->_method[] = $method;
}
}
public function submit()
{
$uriGetParam = isset($_GET['uri']) ? '/' . $_GET['uri'] : '/';
foreach ($this->_uri as $key => $value) {
if (preg_match("#^$value$#", $uriGetParam)) {
$useMethod = $this->_method[$key];
new $useMethod(); // this returns an error (cannot find Home'
new Home(); // this actually works.
}
}
}
}
new $useMethod(); does not work. returns error 'cannot find Home'
new Home(); actually works.
What am I missing here?
You can use your concurrent way for calling a class or you can use this:
call_user_func(array($classname,$methodname))
I was trying one trick with the zendframework , I wanted to created a class that generate the dbTable automaticaly :
here is the class i defined :
class DbTable extends Zend_Db_Table_Abstract {
public $db_table;
public function __construct ($model_name='')
{
//echo "setting database";
$this->db_table = $this->get_db_table($model_name);
}
public function get_db_table($model_name='')
{
if(!empty($model_name))
{
$model = 'Application_Model_DbTable_'.ucfirst($model_name);
if (null === $this->db_table)
{
$this->set_db_table($model);
}
return $this->db_table;
}
else
{
throw new Exception('Database Table was not defined');
}
}
public function set_db_table($dbTable)
{
if (is_string($dbTable)) {
$dbTable = new $dbTable();
}
if (!$dbTable instanceof Zend_Db_Table_Abstract) {
throw new Exception('Invalid table data gateway provided');
}
return $this->db_table = $dbTable;
}
}
and when I try to use it on the for example the User model to find a user with it's id with the function i defined:
public function find_by_id($id=0)
{
$DbTable = new DbTable('User');
$result = $database->find($id);
if(empty($result))
{
return false;
}
else
{
$row = $result->current();
$entry = $this->instantiate($row);
return $entry;
}
}
i get the error mentioned above !
Any help ? thanks anyway !
I think you miss adapter.
Try this:
Replace
$DbTable = new DbTable('User');
$result = $database->find($id);
by
$DbTable = new DbTable('User');
$result = $DbTable->db_table->find($id);
I am trying to set up multidb. The multiple datatbase connections will be coming dynamically entered by users using a form.
bootstrap.php
private $_session = null;
public function init() {
Zend_Session::start();
$this->_session = new Zend_Session_Namespace();
}
protected function _initDb()
{
$resource = $this->getPluginResource('multidb');
Zend_Registry::set("multidb", $resource);
}
indexcontroller.php
public function indexAction()
{
// action body
$request = $this->getRequest();
$form = new Application_Form_Project();
if ($this->getRequest()->isPost()) {
if ($form->isValid($request->getPost())) {
$x = $form->getValues();
//return $this->_helper->redirector('index');
$dbAdapter = Zend_Db::factory("pdo_sqlite", array("dbname"=>"/../data/db/".$x["username"].".db"));
Zend_Db_Table::setDefaultAdapter($dbAdapter);
//print_r($dbAdapter);
Zend_Registry::set('index', $dbAdapter);
$this->_redirect('/line');
}
}
$this->view->form = $form;
}
Application_Model_PgeLine2DMapper
protected $_dbTable;
public function setDbTable($dbTable)
{
$multidb = Zend_Registry::get("multidb");
$registry = Zend_Registry::getInstance();
print_r($registry);
foreach ($registry as $index => $value) {
echo "Registry index $index contains: ";
var_dump($value);
echo "<br>";
}
if (is_string($dbTable)) {
$dbTable = new $dbTable($multidb->getDb('db1'));
}
if (!$dbTable instanceof Zend_Db_Table_Abstract) {
throw new Exception('Invalid table data gateway provided');
}
$this->_dbTable = $dbTable;
return $this;
}
public function getDbTable()
{
if (null === $this->_dbTable) {
$this->setDbTable('Application_Model_DbTable_PgeLine2D');
}
return $this->_dbTable;
}
public function save(Application_Model_PgeLine2D $pgeLine2D)
{
$data = array(
'PGA_Name' => $pgeLine2D->getPGA_Name()
);
if( null === ($id = $pgeLine2D->getPGA_Id()) ) {
unset($data['id']);
$this->getDbTable()->insert($data);
} else {
$this->getDbTable()->update($data, array('PGA_Id = ?' => $id));
}
}
public function find($id, Application_Model_PgeLine2D $pgeLine2D)
{
$result = $this->getDbTable()->find($id);
if (0 == count($result)) {
return;
}
$row = $result->current();
$pgeLine2D->setPGA_Id($row->PGA_Id)
->setPGA_Name($row->PGA_Name);
}
public function fetchAll()
{
$resultSet = $this->getDbTable()->fetchAll();
$entries = array();
foreach ($resultSet as $row) {
$entry = new Application_Model_PgeLine2D();
$entry->setPGA_Id($row->PGA_Id)
->setPGA_Name($row->PGA_Name);
$entries[] = $entry;
}
return $entries;
}
error i get is below
Fatal error: Uncaught exception 'Zend_Db_Adapter_Exception' with message 'Configuration array must have a key for 'dbname' that names the database instance' in /opt/eposdatatransfer/library/Zend/Db/Adapter/Pdo/Sqlite.php:110 Stack trace: #0 /opt/eposdatatransfer/library/Zend/Db/Adapter/Abstract.php(183): Zend_Db_Adapter_Pdo_Sqlite->_checkRequiredOptions(Array) #1 /opt/eposdatatransfer/library/Zend/Db/Adapter/Pdo/Sqlite.php(94): Zend_Db_Adapter_Abstract->__construct(Array) #2 /opt/eposdatatransfer/library/Zend/Db.php(270): Zend_Db_Adapter_Pdo_Sqlite->__construct(Array) #3 /opt/eposdatatransfer/library/Zend/Application/Resource/Multidb.php(99): Zend_Db::factory('PDO_SQLITE', Array) #4 /opt/eposdatatransfer/library/Zend/Application/Bootstrap/BootstrapAbstract.php(683): Zend_Application_Resource_Multidb->init() #5 /opt/eposdatatransfer/library/Zend/Application/Bootstrap/BootstrapAbstract.php(626): Zend_Application_Bootstrap_BootstrapAbstract->_executeResource('multidb') #6 /opt/eposdatatransfer/library/Zend/Application/Bootst in /opt/eposdatatransfer/library/Zend/Db/Adapter/Pdo/Sqlite.php on line 110