Error when Extending a class - php

Im having problems extending a Class.
This is what I was trying to do:
class Core
{
protected $db;
public function __construct()
{
$this->set_db_class();
}
private function set_db_class ()
{
include_once ( './classes/Database.php' );
$this->db = new Database();
}
}
class Functions extends Core
{
public function __construct()
{
parent::__construct();
}
public static function create_user ()
{
$this->db->query ( "INSERT ..." );
}
}
So, that's the estructure, but my problem is that I'm getting the following error:
Fatal error: Using $this when not in object context in /Applications/XAMPP/xamppfiles/htdocs/own/newsite/classes/class.Functions.php on line 10
What can I do to solve this?

Declare create_user as non-static and call it from an instance, otherwise (as the error message says) you cannot access $this, since $this is always a reference to the current instance. In a static context, there isn't one.
$functions = new Functions();
$functions->create_user();
instead of
Functions::create_user();
If you want to bundle functions that are not logically related to each other, use a namespace and not a class. You can go with an all-static class (every tiny property and method is static so that you don't need an instance at any time), but that's a horrible solution and not what classes should be used for.

Related

How to use one function variable to another function in abstract class

abstract class Dropboxapi {
protected $webAuth;
protected function abi() {
require __DIR__.'/app/Dropbox/autoload.php';
self::start();
self::dropbox_auth();
}
public function start() {
$webAuth = new Dropbox\WebAuth($appInfo,$appName,'path',$csrfTokenStore);
}
public function dropbox_auth() {
$authUrl = $webAuth->start();
}
}
Dropboxapi::abi();
Here i have $webAuth object in start function. When I use this in dropbox_auth it shows Undefined variable: webAuth.
When i use $this->webAuth i'm getting Using $this when not in object context
i tried like self::webAuth also. This is showing Access to undeclared static property:. So I don't understand how to use that.
if the abstract method is defined as protected, the function implementation must be defined as either protected or public, but not private.
Many example are there for abstract class.Just check how you can or not.As you asked without abstract just define the class and function like below.Here all the variable and methods are $this context.
class Dropboxapi {
public $this->webAuth='';
public function abi() {
require __DIR__.'/app/Dropbox/autoload.php';
$this->webAuth = new
Dropbox\WebAuth($appInfo,$appName,'path',$csrfTokenStore);
}
public function dropbox_auth() {
$authUrl = $this->webAuth->start();
}
}
$dropbox = new Dropboxapi();
$dropbox->dropbox_auth();
You are defining things wrong. Abstract class, similar with interface, are tend to be used as "blueprint" class. It means they need to be extended by another classes to be used, and cannot be used by itself as is. Using $this in abstract class is fine, as in documentation of abstract by php.net: http://php.net/manual/en/language.oop5.abstract.php.
What you need to do, is to have another class that inherit / extends that DropBoxApi class of yours, ex:
class DropBoxApi2 extends DropBoxApi
{
}
As class DropBoxApi2 is inherited, then it already has functions and property of it's parent (DropBoxApi). And you can use it like (example):
$api = new DropBoxApi2();
$api->start();
Additionally, the double colon that you use is static operator. Which is far far different concept than abstract.
Sample Code. Replace with your requirement.
you have to make everything as static
abstract class Dropboxapi {
protected static $webAuth;
public static function abi() {
self::start();
self::dropbox_auth();
}
public static function start() {
self::$webAuth = new Stdclass();
}
public static function dropbox_auth() {
var_dump(self::$webAuth);
}
}
Dropboxapi::abi();

PHP class not found with namespaces

I'm new to using namespaces. In this example I made class, which handles database connection and I'm trying to use it inside the other classes. Can you explain what is wrong?
Connection.php
namespace Database;
class Connection
{
private static $instance = null;
private $pdo;
private function __construct()
{
$this->pdo = new PDO("mysql:host=localhost;dbname=database;", "root", "pw");
}
public static function get()
{
if (is_null(self::$instance))
self::$instance = new Connection();
return self::$instance;
}
}
Auth.php
namespace PHPAuth;
use Database\Connection;
class Auth
{
protected $dbh;
public function __construct()
{
$this->dbh = Connection::get();
...
Thanks in advance.
Edit: Ok, now I included autoloader and including class is now working correctly. But now I'm getting error when using $dbh in Auth like $query = $this->dbh->query("SELECT * FROM...");
Fatal error: Call to undefined method Database\Connection::query()
in...
First issue with class not found
I'll add the answer (which worked for you) for the first issue for reference: "Namespaces doesn't automatically load the files. You need to add an autoloader for that."
Second issue with undefined method
Fatal error: Call to undefined method Database\Connection::query()
The answer is in the error message. You've made the class Database\Connection into a singleton where Database\Connection::get() returns an instance of itself (which doesn't have any ->query() method), and not the actual PDO instance.
If you want that method to return the PDO instance instead, I would do something like this:
namespace Database;
use PDO;
class Connection
{
private static $pdo;
private function __construct()
{
// Leave the constructor private so it still becomes
// a singleton and so we can't instantiate this class.
}
public static function get()
{
if (is_null(self::$pdo)) {
self::$pdo = new PDO("mysql:host=localhost;dbname=database;", "root", "pw");
}
return self::$pdo;
}
}
Now the Connection class have become a Factory for the PDO-connection.
Connection::get() will return the same PDO instance over and over and you should be able to call $this->dbh->query("...") from your Auth class.

Class Construct Static Undefined method

I am baffled why I get this error:
class smTitan {
private static $_instance = null;
public static function this($att){
if (!self::$_instance) self::$_instance = new self();
if ($att !== NULL) {
self::$_instance->_att = $att;
self::$_instance->_results = new WP_Query( $att );
}
return self::$_instance;
}
}
We extend it
class ourmissionHelper extends smTitan {
public function getPostView() {
}
}
Call it:
ourmissionHelper::this(array("post_type"=>"about"))->getPostView();
and I get this error:
Fatal error: Call to undefined method smTitan::getPostView()
That makes no since to me, getPostView is part of ourmissionHelper which extends smTitan, so it should be able to access it, but its treating the first class from the this() construct as the only instance... Any ideas, other than copying over the class to get this to work?
self always refers to the class that it is written in, never any extending classes. You want a late-binding static reference to your class, which is only possible since PHP 5.3 using the static keyword. So, new static() instead of new self().

PHP Dependency injection and extending from an umbrella class

I have a database class that has a series of functions in it, and I was advised the best thing to do to access those functions from within another class is dependency injection. What I want to do is have one main class that has the database dependency "injected" into it and then other classes extend off of this class, such as Users, Posts, Pages etc.
This is the main class that has the database dependency injected into it.
class Main {
protected $database;
public function __construct(Database $db)
{
$this->database = $db;
}
}
$database = new Database($database_host,$database_user,$database_password,$database_name);
$init = new Main($database);
And then this is the Users class I'm trying to extend off of it.
class Users extends Main {
public function login() {
System::redirect('login.php');
}
public function view($username) {
$user = $this->database->findFirst('Users', 'username', $username);
if($user) {
print_r($user);
} else {
echo "User not found!";
}
}
}
But whenever trying to call the view function for the User class, I'm getting this error Fatal error: Using $this when not in object context. This error is in regards to trying to call $this->database in the Users class. I've tried initializing a new user class and passing the database to it instead, but to no avail.
When you use call_user_func_array and you pass it a callable that is composed of a string name for the class and a string name for the method on the class it does a static call: Class::method(). You need to first define an instance and then pass the instance as the first part of the callable as demonstrated below:
class Test
{
function testMethod($param)
{
var_dump(get_class($this));
}
}
// This call fails as it will try and call the method statically
// Below is the akin of Test::testMethod()
// 'this' is not defined when calling a method statically
// call_user_func_array(array('Test', 'testMethod'), array(1));
// Calling with an instantiated instance is akin to $test->testMethod() thus 'this' will refer to your instnace
$test = new Test();
call_user_func_array(array($test, 'testMethod'), array(1));

Php access a Global Class

this has been driving me nuts (Drinking Obscene amounts of Coffee and working all night doesn't help) I want to gain access to a class from wherever I am within the application. I instantiate the Class within my index page (which auto loads my lib/classes)But it seems I cannot gain global access to it. This is my index page:
function __autoload($class)
{
require LIBS . $class .'.php';
}
$Core = new Core($server, $user, $pass, $db);
This auto load my Lib/classes perfectly and then I instantiate my Core (This is auto loaded within my Lib/core.php)
Then within my Core is where I create the usual, a database connection, get and check the URL and where I instantiate a few classes (Which are auto loaded) I create a __construct and this is where I want to instantiate a Template class. I wish to have global access for accessing the class within any of my controllers and models.
class Core {
function __construct(DATABASE VARIABLES IN HERE)
{
$this->Template = new Template();
}
}
Ok so I thought I could access the Template Object by doing the following within my parent model and parent controller:
class Controller
{
public $Core;
function __construct()
{
global $Core;
$this->Core = &$Core;
}
}
The Controller is a parent extends all my controllers, therefore I assumed I could just write $this->Core->Template->get_data(); to access the a Template Method? This Seems to throw an error.
Im sure it must be something simple that I have overlooked, if anyone can give me a hand that would be great. This problem is driving me crazy.
Also a side note within my child controllers within my __construct I construct the Parent parent::_construct();
The Error seems to be Notice: Trying to get property of non-object and Fatal error: Call to a member function get_data() on a non-object.
class Controller
{
public $Core;
function __construct(Core $core)
{
$this->Core = $core;
}
}
class ControllerChild extends Controller {
function __construct(Core $core, $someOtherStuff){
parent::__construct($core) ;
//And your $this->Core will be inherited, because it has public access
}
}
note: You dont have to use & sign when working with objects. Objects are automatically passed by reference.
You could make Core a singleton and implement a static function to receive a pointer to the object.
define ('USER', 'username');
define ('PASS', 'password');
define ('DSN', 'dsn');
class Core {
private static $hInstance;
public static function getInstance() {
if (!(self::$hInstance instanceof Core)) {
self::$hInstance = new Core(USER, PASS, DSN);
}
return self::$hInstance;
}
public function __construct($user, $pass, $dsn) {
echo 'constructed';
}
}
Then within your Controller you can use:
$core = Core::getInstance();
Which should output constructed.
Edit
Updated to demonstrate how to construct via the static function w/ output.

Categories