PHP cannot extends 2 class - php

i try work with the a class of database, and connect it to wipe it I build using extends, but I get an error. Example:
class Admin extends Sdba{
// Var:
public $login = false;
public $users;
public $users_list;
// Function:
public function UserLogin($char) {
if($this->login) {
print "in";
}else{
$this->users = Sdba::table('users'); // creating table object
$this->users_list = $this->users->get();
print_r($this->user_list);
print "out";
}
}
}
and my DB class is:
http://foska.pp.ua/codecanyon/sdba/
my error is: Fatal error: Call to private Sdba::__construct() from invalid context
Tanks !!

You are inheriting from Sdba class, and when you do that, the actual method: Sdba::table can be referenced as self::table in your child class.
Therefore, the code for creating table object should use:
$this->users = self::table('users'); // creating table object
You can also use parent::table to reference your function. But, the benefit of using self over parent is that you can further modify your table method in this child class, if need arises.

it should use parent::table because you use table method from extended class
$this->users = parent::table('users'); // creating table object

Related

new $this->table() vs. new tablename(); dynamic class generation

I have the following classes:
namespace database;
class database {
protected $table = '';
function __construct()
{ // Stuff here }
public function all() {
// Load from database
// Return array with results
}
}
class tbl_organisation_types extends database {
protected $table = 'tbl_organisation_types';
function __construct($data = [])
{
parent::__construct();
// do stuff with $data
}
}
I fetch all rows from the database, iterate through them and create new objects. Since other classes extend this database class, the generated objects have to be dynamic.
When i try to generate the objects dynamically like this
$return[] = new $this->table($row);
I get the following error
Uncaught Error: Class 'tbl_organisation_types' not found in /path/to/tbl_organisation_types.php
If I generate the objects with a fixed classname like this it works. But then it wouldn't work for multiple classes.
$return[] = new tbl_organisation_types($row);
Is there a way to dynamically generate objects and/or why is mine not working?
Using PHP 7.1
I am getting an impression, that you are attempting to create something like active record there. I would advise against that.
As for why your class is not working, you probably should do something like:
$name = '\\database\\' . $this->table;
$instance = new $name($row);
When you use a string to initialize class, it has to contain the fully qualified class name, no matter in which namespace your code is. And same applies even to aliases.

Pass a parent class as a parameter to a function

This is a basic PHP question, and somehow I couldn't find any information about it.
So what I'm trying to do is to pass a parent class to a function so all of its children class can be passed too.
Is there anyway to do it?
function transform(Fruit $fruit){}
transform($orange)
transform($apple)
Update :
Looks like I need to show the situation more.
So what I have is a transformer parent
class ResourceTransformer{
public function transform(ResourceModel $model){}
}
And its child
class ColorTransformer extends ResourceTransformer{}
Now what I want to do is passing ColorModel, a child of ResourceModel to ColorTransformer.
class ColorModel extends ResourceModel{}
when I'm doing that it throws an error like this:
Type error: Argument 1 passed to App\\Modules\\Product\\Transformer\\ResourcesTransformer::transform() must be an instance of App\\Modules\\Product\\Models\\ResourceModel, instance of App\\Modules\\Product\\Models\\ColorModel given.
So basically, ColorTransformer can't accept ColorModel and only accept ResourceModel, yet ColorModel is a child of ResourceModel. Might be some of you can give me more enlightement.
I have tried this code to check your problem
class ResourceModel { }
class ResourceTransformer
{
public function transform(ResourceModel $model)
{
var_dump($model);
}
}
class ColorTransformer extends ResourceTransformer { }
class ColorModel extends ResourceModel { }
$transformer = new ColorTransformer();
$model = new ColorModel();
$transformer->transform($model);
and i've got correct result
object(ColorModel)#2 (0) { }
If this is not working in your case then it's look like the class ResourceModel form this part of your code
class ResourceTransformer{
public function transform(ResourceModel $model){}
}
is not the same that in this part
class ColorModel extends ResourceModel{}
You told in comment that the problem is only with the ColorModel but your information about error tell us that namespaces for ResourceModel and ColorModel are the same so I think the problem is with your ResourceTransformer class definition - do you have this code somewhere in top of your file with this definition?
use App\Modules\Product\Models\ResourceModel;
If you don't then do you have an another declaration of the ResourceModel class somewhere in your file with ResourceTransformer class definition?
The other thing I see in your question is the difference between this part of your code
class ResourceTransformer{
public function transform(ResourceModel $model){}
}
and class name in your error
Type error: Argument 1 passed to App\Modules\Product\Transformer\ResourcesTransformer::transform() must be an instance of App\Modules\Product\Models\ResourceModel, instance of App\Modules\Product\Models\ColorModel given.
Look that in error you have a class ResourcesTransformer and you tell us that this class is named ResourceTransformer. If this difference is ok then your problem should be placed in file with declaration of the ResourcesTransformer class.
You can simply pass name of class as a string and dinamically instantiate it:
function transform($name_of_class){
...
new $name_of_class;
}
Check the example please;
<?php
// function transform(Fruit $fruit){ //or
function transform($fruit){
print_r($fruit);
}
class Fruit{
public $name = null;
function __construct($name){
$this->name = $name;
}
}
transform(new Fruit('Apple')); // result: Fruit Object ( [name] => Apple )
echo '<br />';
$orange = new Fruit('Orange');
transform($orange); // result: Fruit Object ( [name] => Orange )

Accessing parent class objects & variables through $this?

I have one main class "main", which I use to store the configuration and a few objects. However, I am unable to access the objects & variables in a class which extends main, through $this.
Here is some of my main class:
<?php
class main{
// the configuration vars
public $config = array();
// the current user variables
public $uid; // contains the user ID
public $gid; // contains the group ID
// database variables
public $DB; // contains the connection
public $query_id; // contains the query ID
public $query_count; // how many queries have there been?
// cache variables
public $cache;
// start up functions
public function startup(){
// first, set up the caching
if(function_exists('memcache_connect') AND $this->config['use_memcache'] == true){
// start up memcache
require_once('memcache.class.php');
$this->cache = Cache::getInstance();
}
// now, set up the DB
$this->connectToDatabase();
// now, set up the user session
$this->setUserSession();
// are we logged in? If so, update our location
if($this->uid > 0){
// update location
$this->updateUserSession();
}
}
Here is an example of another class
<?php
class user extends main{
public function viewProfile($uid){
exit($this->config['session_prefix']); // displays nothing
if($this->cache->exists('key')){ // fails
The $config value is correctly set up, and I can read it within main but not any sub class.
The $cache->exists object just results in Call to a member function exists() on a non-object.
On index.php, the classes are loaded and set up. The Main class is setup first, and the startup function is called. The configuration array is passed before startup is called.
Can anyone suggest how I can fix this?
Are you sure your array is correctly set up.
This simple test works for me:
<?
class main {
public $test = "Woot";
}
class test extends main {
public function __construct() {
echo $this->test;
}
}
$t = new test();
Just for testing purposes, add a variable $test like in my example to the class main and try to echo it in the user constructor.
I would check if your cache is really set up correctly.
Probably the error is in this if statement:
if(function_exists('memcache_connect') AND $this->config['use_memcache'] == true){
One of these two conditions isn't met, so your $cache variable won't get initialized.
you can use parent:: to referance variables in the parent class.
parent::cache->exists('key')
You can access parent class's attributes by $this->attribute, so the problem should be that you are not calling the constructor of the parent...
Like this code is perfectly working:
<?php
class foo {
public $x="aa";
}
class bar extends foo {
public function barbar()
{
echo $this->x;
}
}
$b = new bar;
$b->barbar();
?>
Though you can also access parent class properties by Parent::attr()

What is the proper method of structuring PHP classes as Parent Child?

I have the following PHP Classes
class.property.php
class.location.php
class.amenity.php
class.category.php
all four classes handles the respective CRUD operations for different categories. i want to refactor my codes and hence wants to go with the Parent Child Structure.
for example i used to initialize classes on every page like this.
$property = new Property($dbh);
$location = new Location($dbh);
$category = new Category($dbh);
$amenity = new Amenity($dbh);
and then i used to access class methods and properties individually like
$property->user;
$property->contact;
$property->save();
$location->countries();
$location-states();
Andso on, every class is executing indivdually, instead of accessing it like this i would like to use it this way.
$property = new Property($dbh)
above should be the Parent class and rest three child class, and so i should be able to access all class methods and properties only through parent class for example i should only be able to access it like this..
$property->location->countries();
$property->locations->states();
$property->location->countryId;
$property->amenity->name;
$property->amenity->save();
and so on..
i tried to figure out how to do it and came out with this solution.
class Property{
public $amenity;
public function __construct() {
require_once('class.amenity.php');
$this->amenity = new Amenity;
}
}
class Amenity {
public function create($test) {
return $test;
}
}
now if i want to access the create() method in Amenity class i simply call
$property->amenity->create()
and it works, however i would like to know if this is the correct method of implementing the Parent Child Structure or am i missing something?
There is no need for the create() call:
class Property{
public $amenity;
public function __construct() {
require_once('class.amenity.php');
$this->amenity = new Amenity;
}
}
class Amenity {
}
$property = new Property;
$amenity = $property->amenity;
At the very most, you'll want to make the properties protected, and use getters and setters.

Create a PHP Class -> Create an object of it in another class

I have created a PHP class called formChecker.php. It validates a form. As a Java programmer, I would like to stick with the idea of creating an instance of this class in another class and run it from there. It doesn't seem to be working for me.The following is a demonstration:
class formChecker{
..... validation functions go here
}
class runFormChecker{
.... create instance of formchecker here and use it's methods etc.
}
Can this be done? What I'm thinking of is developing a number of classes that can be run seperately.
GF
I'd rather pass the instance of formChecker (or something that implements a certain interface) to the instance of runFormChecker. see http://en.wikipedia.org/wiki/Dependency_injection
Could be as simple as
interface FormChecker {
public function foo($x);
}
class MyFormChecker implements FormChecker
public function foo($x) {
return true;
}
}
class RunFormChecker {
protected $formChecker=null;
public function __construct(FormChecker $fc) {
$this->formChecker = $fc;
}
// ....
}
$rfc = new RunFormChecker(new MyFormChecker);
Just include the formChecker class file just before the class you want to use it in eg:
include "formChecker.php"
class runFormChecker{
function __construct() {
$obj = new formChecker; // create instance
// more processing............
}
}
If however, you have both classes in one file (which is bad), then no need to include the file, you can create the instance of that straight away eg:
class formChecker{
// ............
}
class runFormChecker{
function __construct() {
$obj = new formChecker; // create instance
// more processing............
}
}
More Information Here....
Thanks :)
Yes, and this is not strange. You would usually create the instance of formChecker within an instance of runFormChecker though, and not at the class level.

Categories