I am building an MVC component and I'm getting stuck with an issue with a parent and child model. I have a few methods in the parent Model and they're not working with the database_class object
the constructor works fine
but when I use that object in the methods its like the constructor doesn't exist?
Class Controlller
{
public function __construct()
{
$this->childModel = $this->model('childModel');
} // end construct
// methods go here
}
Here are the models:
class childModel extends parentModel {
private $dbo;
public function __construct()
{
$dbobj = new Database_class;
$this->dbo = $dbobj;
}
//methods
}
class parentModel {
private $dbom;
public function __construct()
{
$dbombj = new Database_class;
$this->dbom = $dbombj;
var_dump($this->dbom); //working perfectly as database object
}
public function methodName()
{
var_dump($this->dbom); //not showing up as database object
}
}
I don't think this code is doing what you think it's doing. In childModel, you are overwriting the __construct method of the parentModel, so the __construct in the parentModel never gets called. Therefore $this->dbom should be null. Furthermore if you wish to use $this->dbom from the childModel, you should probably change the scope from private $dbom to protected $dbom. See this page for more info on that: http://php.net/manual/en/language.oop5.visibility.php
I am trying out a MVC concept where the main model for a database stems or trees off other models. I wanted to have a main database sort of model which does the connecting and queries. Then, other models are built to support the controller. Ie, a product model can be extended off the main database model to then query rather than using dependency injection.
My current ideology and attempt looks like this for the main database model:
namespace Portfolio\Application;
abstract class DriverModel {
private static $driver;
private $entity;
private function __construct() {
// Connection to the PDO will be done in here
}
private function __clone() {}
public static function getInstance() {
if(self::$driver)
return self::$driver;
self::$driver = new self();
return self::$driver;
}
protected function q($sql, $values = []) {
$stmt = $this->entity->Prepare($sql);
$stmt->execute($values);
return $stmt;
}
}
Then my example profile controller would look something like this (having the methods to use the main database to run queries):
class ProfileModel extends DriverModel {
public function doSomeQ() {
$this->q('SELECT fname FROM users WHERE id = ?', [(int)1]);
}
}
However, When I execute this line of code:
print_r(ProfileModel::getInstance()->doSomeQ());
I am left with this error: (which makes sense.)
Uncaught Error: Cannot instantiate abstract class.
I then remove the abstract attribute from the class (class DriverModel) but now, the instance I am receiving is the instance from the parent class meaning if I do a print_r() on the getInstance() method to the ProfileModel, there is no doSomeQ() method.
Any help on achieving this methodology would be helpful.
You have to use get_called_class() method instead of new self();
http://php.net/manual/en/function.get-called-class.php
Attached you can find sample who show your expected behaviour
class Main {
public static function getInstance() {
$class = get_called_class();
return new $class();
}
}
class Foo extends Main{
}
var_dump(Foo::getInstance()); // Output Foo object
I don't understand what is the different between private method and protected method in Object Oriented PHP. After make a method private , I'm able to access it from extends class. Please check the code below -
<?php
class person{
private function namedilam(){
return "likhlam";
}
public function kicu(){
return $this->namedilam();
}
}
class second extends person{
}
$info = new second;
echo $info->kicu();
The difference will become clear when you do it like this:
class Liam {
private getFirstName() {
return "Liam";
}
public function getName() {
return $this->getFirstName();
}
}
class Max extends Liam {
private function getFirstName() {
return "Max";
}
}
class Peter extends Liam {
public function getLiamsName() {
return $this->getFirstName();
}
}
$max = new Max();
echo $max->getName();
// returns "Liam", not "Max" as you might expect
$peter = new Peter();
echo $peter->getLiamsName();
// PHP Fatal error: Uncaught Error: Call to private method Liam::getFirstName() [...]
Max will return "Liam" because the getName() calls getFirstName() in the Liam class, not the one from the class extending it. This means with private methods you can make sure that whenever in your class you call this method exactly this one is used and it will never be overwritten.
To explain it in general terms:
private methods are only accessible inside the class. They can not be overwritten or accessed from outside or even classes extending it.
protected methods are accessible inside the class and in extending classes, but you can't call them from outside like:
$max = new Max();
$max->iAmProtected();
This will neither work with private or protected methods.
I have a protected function that is defined within a certain class. I want to be able to call this protected function outside of the class within another function. Is this possible and if so how may I achieve it
class cExample{
protected function funExample(){
//functional code goes here
return $someVar
}//end of function
}//end of class
function outsideFunction(){
//Calls funExample();
}
Technically, it is possible to invoke private and protected methods using the reflection API. However, 99% of the time doing so is a really bad idea. If you can modify the class, then the correct solution is probably to just make the method public. After all, if you need to access it outside the class, that defeats the point of marking it protected.
Here's a quick reflection example, in case this is one of the very few situations where it's really necessary:
<?php
class foo {
protected function bar($param){
echo $param;
}
}
$r = new ReflectionMethod('foo', 'bar');
$r->setAccessible(true);
$r->invoke(new foo(), "Hello World");
That's the point of OOP - encapsulation:
Private
Only can be used inside the class. Not inherited by child classes.
Protected
Only can be used inside the class and child classes. Inherited by child classes.
Public
Can be used anywhere. Inherited by child classes.
If you still want to trigger that function outside, you can declare a public method that triggers your protected method:
protected function b(){
}
public function a(){
$this->b() ;
//etc
}
If the parent's method is protected, you can use an anonymous class:
class Foo {
protected function do_foo() {
return 'Foo!';
}
}
$bar = new class extends Foo {
public function do_foo() {
return parent::do_foo();
}
}
$bar->do_foo(); // "Foo!"
https://www.php.net/manual/en/language.oop5.anonymous.php
You can override this class with another where you make this public.
class cExample2 extends cExample {
public function funExample(){
return parent::funExample()
}
}
(note this won't work with private members)
But the idea of private and protected members is to NOT BE called from outside.
Another option (PHP 7.4)
<?php
class cExample {
protected function funExample(){
return 'it works!';
}
}
$example = new cExample();
$result = Closure::bind(
fn ($class) => $class->funExample(), null, get_class($example)
)($example);
echo $result; // it works!
If you want to share code between your classes you can use traits, but it depends how you want use your function/method.
Anyway
trait cTrait{
public function myFunction() {
$this->funExample();
}
}
class cExample{
use cTrait;
protected function funExample() {
//functional code goes here
return $someVar
}//end of function
}//end of class
$object = new cExample();
$object->myFunction();
This will work, but keep in mind that you don't know what your class is made of this way. If you change the trait then all of your classes which use it will be altered as well. It's also good practice to write an interface for every trait you use.
here i can give you one example like below
<?php
class dog {
public $Name;
private function getName() {
return $this->Name;
}
}
class poodle extends dog {
public function bark() {
print "'Woof', says " . $this->getName();
}
}
$poppy = new poodle;
$poppy->Name = "Poppy";
$poppy->bark();
?>
or one another way to use with latest php
In PHP you can do this using Reflections. To invoke protected or private methods use the setAccessible() method http://php.net/reflectionmethod.setaccessible (just set it to TRUE)
I am using Laravel. i was facing issue while access protected method outside of class.
$bookingPriceDetails = new class extends BookingController {
public function quotesPrice( $req , $selectedFranchise) {
return parent::quotesPrice($req , $selectedFranchise);
}
};
return $bookingPriceDetails->quotesPrice($request , selectedFranchisees());
here BookingController is Class name from which i want to get protected method. quotesPrice( $req , $selectedFranchise) is method that i want to access in different Class.
A parent class is constructed from outside the child class, thus, it's constructor cannot be called from inside the child. How should one go about accessing properties of the parent from the child in this case.
Example:
class MyParent {
protected $args;
protected $child;
public function MyParent($args=false){
$this->args=$args;
$this->child=new MyChild();
}
public function main(){
$this->child->printArgs();
}
}
class MyChild extends MyParent{
public function MyChild(){}
public function printArgs(){
Echo "args: ".$this->args['key']." = ".$this->args['value']."\n";
}
}
$parent=new MyParent(array('key'=>'value'));
$parent->main();
Empty variables are returned when run:
jgalley#jgalley-debian:~/code/otest$ php run.php
args: =
__construct() is the constructor. You are using a variant from ancient PHP4-times.
You instanciate two completely different objects, therefore of course the property $args is completely independent.
abstract class MyParent {
protected $args;
public function __construct($args=false){
$this->args=$args;
}
public function main(){
$this->printArgs();
}
abstract public function printArgs();
}
class MyChild extends MyParent{
public function printArgs(){
Echo "args: ".$this->args['key']." = ".$this->args['value']."\n";
}
}
$$object=new MyChild(array('key'=>'value'));
$object->main();
This at least works, but a problem is, that I don't know exactly what are the design goals. Because it seems to be a kind of cli-Application you should have a look at existing solutions to get an idea, how it could get solved.