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
How to solve this problem the best way? Maybe any pattern was created for this?
I have class Master, which through the DI manage a Slave object. Instance of the class Slave must have parent Master internal. Something like this:
class Master
{
private $slave;
public function __construct(Slave $slave)
{
$slave->registerMaster($this);
$this->slave = $slave;
}
}
class Slave
{
private $master;
public function registerMaster(Master $master)
{
$this->master = $master;
}
}
Only class Master could call registerMaster method. Is any way, pattern which will help me in this example?
Only class Master could call registerMaster method. Is any way, pattern which will help me in this example?
There is no concept of Friend Classes in PHP, so there is no way to hide a public method from another class.
You could use inheritance and protected visibility
abstract class LinkedEntity {
protected $master;
protected $slave;
}
class Master extends LinkedEntity {
public function __construct(Slave $slave) {
$this->slave = $slave;
$this->slave->master = $this;
}
}
class Slave extends LinkedEntity {}
$slave = new Slave;
$master = new Master($slave);
Since Master and Slave now extend the same base class, the protected properties are accessible to them, but not to any other classes. The same would be true for protected methods defined in the LinkedEntity class. So you can put a protected registerMaster(Master $master) method and go through that instead of directly assigning the properties.
Personally, I find that not so pretty and I'd rather find out whether you really need the bidirectional association here or whether it's good enough to have a one way association, e.g. from Master to Slave only or vice versa.
Another, even worse option, would be to inspect the callstack:
class Slave {
private $master;
public function registerMaster(Master $master)
{
if (debug_backtrace(null, 2)[1]["class"] === Master::class) {
throw new RuntimeException("Only Masters may call Slaves");
}
$this->master = $master;
}
}
The method checks if the previous class in the call stack (the one that did the call to your registerMaster was actually a Master. However, when your methods depend on the information of who the callee was, it's usually a sign of bad design.
A third option would be to break through the visibility of the method in the Slave via Reflection, e.g.
class Master {
private $slave;
public function __construct(Slave $slave) {
$this->slave = $slave;
$fn = new ReflectionMethod($slave, 'registerMaster');
$fn->setAccessible(true);
$fn->invoke($slave, $this);
}
}
class Slave {
private $master;
private function registerMaster(Master $master)
{
$this->master = $master;
}
}
Again, this is not optimal, because a core principle of OOP is Information Hiding and we are breaking it here. We are breaking through the designated private visibility and force it to public for the Master. Also, this will not prevent any other objects from doing the same.
Another way of avoiding extra methods in the class is to bind a closure to the private scope of another class, so you will be able to access all methods and properties directly:
class Master
{
private $slave;
public function __construct(Slave $slave)
{
$this->slave = $slave;
$master = $this;
$masterInjector = function (Master $master) {
$this->master = $master;
};
$masterInjector->call($slave, $master);
}
}
class Slave
{
private $master;
}
There are many topics about this already, but I have not a clear picture of why factory patterns are better practice than Singleton.
An example
class MySingleton {
public static function numberByWhat( $number ) {
return $number + 100;
}
public static function someCharacters( $string ) {
return $string + 'abc';
}
}
class MyOtherSingleton {
public static function getImage( $url ) {
return '<img src="' . $url . MySingleton::numberByWhat( $50 ) . '">';
}
public static function getTextById( $id ) {
if( $id == 3 ) {
return 'this is my text' . MySingleton::someCharacters( 'Yeah' );
}
}
}
function run() {
echo MyOtherSingleton::getImage( 'http://www.example.com/image.png' );
echo MyOtherSingleton::getTextById( 3 );
}
run();
So there we have 2 classes and a function. When I run() I start a function in the second class. Inside the functions in the second class there are calls to the first class.
How would this look like as a factory pattern?
Why is it better as a factory pattern?
So the examples you've given are neither Singletons nor Factories. What you have here are simply "static classes"--classes with only static methods and properties. Factories and Singletons don't really solve the same problem, either, so it's difficult to compare and contrast them.
Singletons
A Singleton is used to manage shared state or avoid the overhead of instantiating a class multiple times when you only really need "one of something".
Here's an example of a Singleton:
class DatabaseConnection {
// Static reference to the single instance of this class we maintain.
protected static $instance;
// Normal instance properties.
protected $mysql;
// Protected constructor to prevent "new DatabaseConnection();"
protected function __construct() {
$this->mysql = new MySQLConnection("localhost", 3306, "appdb");
}
public static function getInstance() {
if (!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
public function query($sql) {
return $this->mysql->query($sql);
}
}
Whenever you want to use the DatabaseConnection() in your code, you do it like this:
function getUser($userId) {
$userData = DatabaseConnection::getInstance()->query("SELECT * FROM ...");
}
The DatabaseConnection() is only instantiated once, starting the first time it is used. There will never be more than one created.
Dependency Injection / Inversion of Control
The competing strategy to using a Singleton is, basically, Dependency Injection or Inversion of Control. With Dependency Injection, instead of having one shared, staticly-stored instance of a class, the instance is simply passed from class to class and function to function. Here's a simple example:
class DatabaseConnection {
// Normal instance properties.
protected $mysql;
public function __construct() {
$this->mysql = new MySQLConnection("localhost", 3306, "appdb");
}
public function query($sql) {
return $this->mysql->query($sql);
}
}
class UserManager {
protected $databaseConnection;
public function __construct(DatabaseConnection $databaseConnection) {
$this->databaseConnection = $databaseConnection;
}
public function lookupUser($userId) {
return $this->databaseConnection->query("SELECT ...");
}
}
One advantage of Dependency Injection is that you can test your code much more easily. You could, for example, extend DatabaseConnection and call it TestDatabaseConnection, and make it not actually use a real MySQL database, which can make your tests faster and more reliable. So, the debate is really between Singletons and Dependency Injection / Inversion of Control, not Factories.
Factories
So, now, Factories: Factories simplify the creation of objects, return objects of different classes/subclasses, and help to create objects from "templates". As an example, let's say we have different classes to represent different types of users:
class User {
// ...
}
class ModeratorUser extends User {
// ...
}
class AdminUser extends ModeratorUser {
// ...
}
class GuestUser extends User {
// ...
}
Each of these classes contain methods and properties that would be useful for working with a certain type of user account. So, how would you create and return one of these user objects by User ID, ensuring that the correct type of user is returned? We can use a factory pattern:
class UserFactory {
public static function fromUserId(DatabaseConnection $db, $userId) {
$record = $db->query("SELECT * FROM users WHERE user_id ...");
// ...
switch ($record['type']) {
case 'admin':
return new AdminUser($userId);
break;
case 'moderator':
return new ModeratorUser($userId);
break;
case 'guest':
return new GuestUser($userId);
break;
default:
case 'normal':
return new User($userId);
break;
}
}
}
Then, to load the proper User class, you'd just call:
$user = UserFactory::fromUserId($userId);
If it's an admin account, it will be an AdminUser; if it's a guest account, it will be a GuestUser.
I am trying to make the jump towards object orientated php. I'm building my own MVC framework from the ground up because I like to have full control and I figure it's a good learning exercise to do.
This is my router which I use to route to different folders according to the name (I have an autoloader function in the index file):
class controller_router
{
public $controller;
public $action;
public $id;
public $freetext;
//set the url path variables
public function __construct($controller,$action,$id,$freetext)
{
$this->controller = $controller;
$this->action = $action;
$this->id = $id;
$this->freetext = $freetext;
}
//instantiate the main controller according to url
public function instantiateMainController()
{
$controller_name = 'controller_'.$this->controller;
$controller = new $controller_name;
}
}
My blog controller looks like this (just testing to see if I can get the action):
class controller_blog
{
public function __construct()
{
echo $this->action;
}
}
My question is - how do I get the action variable from the parent (the router)?
The command echo $this->action; does not appear to work!
Also, any other improvements you could suggest? I am a newbie!
You should pass your object to new object.
$controller = new $controller_name($this);
//...
class controller_blog
{
public function __construct($router)
{
echo $router->action;
}
}
There are several ways to do that in code - but first you need to do that in mind. That means - you need to realize, what is the structure of your application. What structure has each entity? How each entity is implemented in class? How entities are related and how that is implemented in code?
For example, one of options can be inherit your action from parent class. But first you'll need to make your controller_blog child of controller_router. This may have sense - but are they related in such way - is up to you to decide. You can do this with:
class controller_blog extends controller_router
{
public function __construct()
{
echo $this->action;
}
}
-so you'll have one class that will extends another.
But may be they're not related such way? Then you'll need to inject dependency into your blog controller. For example
class controller_blog
{
public $action;
public function __construct(controller_router $router)
{
$this->action = $router->action;
}
}
-since you've not specified your structure, you'll need to decide what is more correct by yourself.
Pass variables from the controller_router to the controller_blog as arguments of the constructor of controller_blog.
I'm building a User Class for my new website, however this time I was thinking to build it little bit differently...
C++, Java and even Ruby (and probably other programming languages) are allowing the use of nested/inner classes inside the main class, which allows us to make the code more object-oriented and organized.
In PHP, I would like to do something like so:
<?php
public class User {
public $userid;
public $username;
private $password;
public class UserProfile {
// some code here
}
private class UserHistory {
// some code here
}
}
?>
Is that possible in PHP? How can I achieve it?
UPDATE
If it's impossible, will future PHP versions might support nested classes?
Intro:
Nested classes relate to other classes a little differently than outer classes. Taking Java as an example:
Non-static nested classes have access to other members of the enclosing class, even if they are declared private. Also, non-static nested classes require an instance of the parent class to be instantiated.
OuterClass outerObj = new OuterClass(arguments);
outerObj.InnerClass innerObj = outerObj.new InnerClass(arguments);
There are several compelling reasons for using them:
It is a way of logically grouping classes that are only used in one place.
If a class is useful to only one other class, then it is logical to
relate and embed it in that class and keep the two together.
It increases encapsulation.
Consider two top-level classes, A and B, where B needs access to
members of A that would otherwise be declared private. By hiding class
B within class A, A's members can be declared private and B can access
them. In addition, B itself can be hidden from the outside world.
Nested classes can lead to more readable and maintainable code.
A nested class usually relates to it's parent class and together form a "package"
In PHP
You can have similar behavior in PHP without nested classes.
If all you want to achieve is structure/organization, as Package.OuterClass.InnerClass, PHP namespaces might sufice. You can even declare more than one namespace in the same file (although, due to standard autoloading features, that might not be advisable).
namespace;
class OuterClass {}
namespace OuterClass;
class InnerClass {}
If you desire to emulate other characteristics, such as member visibility, it takes a little more effort.
Defining the "package" class
namespace {
class Package {
/* protect constructor so that objects can't be instantiated from outside
* Since all classes inherit from Package class, they can instantiate eachother
* simulating protected InnerClasses
*/
protected function __construct() {}
/* This magic method is called everytime an inaccessible method is called
* (either by visibility contrains or it doesn't exist)
* Here we are simulating shared protected methods across "package" classes
* This method is inherited by all child classes of Package
*/
public function __call($method, $args) {
//class name
$class = get_class($this);
/* we check if a method exists, if not we throw an exception
* similar to the default error
*/
if (method_exists($this, $method)) {
/* The method exists so now we want to know if the
* caller is a child of our Package class. If not we throw an exception
* Note: This is a kind of a dirty way of finding out who's
* calling the method by using debug_backtrace and reflection
*/
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
if (isset($trace[2])) {
$ref = new ReflectionClass($trace[2]['class']);
if ($ref->isSubclassOf(__CLASS__)) {
return $this->$method($args);
}
}
throw new \Exception("Call to private method $class::$method()");
} else {
throw new \Exception("Call to undefined method $class::$method()");
}
}
}
}
Use case
namespace Package {
class MyParent extends \Package {
public $publicChild;
protected $protectedChild;
public function __construct() {
//instantiate public child inside parent
$this->publicChild = new \Package\MyParent\PublicChild();
//instantiate protected child inside parent
$this->protectedChild = new \Package\MyParent\ProtectedChild();
}
public function test() {
echo "Call from parent -> ";
$this->publicChild->protectedMethod();
$this->protectedChild->protectedMethod();
echo "<br>Siblings<br>";
$this->publicChild->callSibling($this->protectedChild);
}
}
}
namespace Package\MyParent
{
class PublicChild extends \Package {
//Makes the constructor public, hence callable from outside
public function __construct() {}
protected function protectedMethod() {
echo "I'm ".get_class($this)." protected method<br>";
}
protected function callSibling($sibling) {
echo "Call from " . get_class($this) . " -> ";
$sibling->protectedMethod();
}
}
class ProtectedChild extends \Package {
protected function protectedMethod() {
echo "I'm ".get_class($this)." protected method<br>";
}
protected function callSibling($sibling) {
echo "Call from " . get_class($this) . " -> ";
$sibling->protectedMethod();
}
}
}
Testing
$parent = new Package\MyParent();
$parent->test();
$pubChild = new Package\MyParent\PublicChild();//create new public child (possible)
$protChild = new Package\MyParent\ProtectedChild(); //create new protected child (ERROR)
Output:
Call from parent -> I'm Package protected method
I'm Package protected method
Siblings
Call from Package -> I'm Package protected method
Fatal error: Call to protected Package::__construct() from invalid context
NOTE:
I really don't think trying to emulate innerClasses in PHP is such a good idea. I think the code is less clean and readable. Also, there are probably other ways to achieve similar results using a well established pattern such as the Observer, Decorator ou COmposition Pattern. Sometimes, even simple inheritance is sufficient.
Real nested classes with public/protected/private accessibility were proposed in 2013 for PHP 5.6 as an RFC but did not make it (No voting yet, no update since 2013 - as of 2021/02/03):
https://wiki.php.net/rfc/nested_classes
class foo {
public class bar {
}
}
At least, anonymous classes made it into PHP 7
https://wiki.php.net/rfc/anonymous_classes
From this RFC page:
Future Scope
The changes made by this patch mean named nested classes are easier to implement (by a tiny bit).
So, we might get nested classes in some future version, but it's not decided yet.
You cannot do this in PHP. However, there are functional ways to accomplish this.
For more details please check this post:
How to do a PHP nested class or nested methods?
This way of implementation is called fluent interface: http://en.wikipedia.org/wiki/Fluent_interface
As per Xenon's comment to Anıl Özselgin's answer, anonymous classes have been implemented in PHP 7.0, which is as close to nested classes as you'll get right now. Here are the relevant RFCs:
Nested Classes (status: withdrawn)
Anonymous Classes (status: implemented in PHP 7.0)
An example to the original post, this is what your code would look like:
<?php
public class User {
public $userid;
public $username;
private $password;
public $profile;
public $history;
public function __construct() {
$this->profile = new class {
// Some code here for user profile
}
$this->history = new class {
// Some code here for user history
}
}
}
?>
This, though, comes with a very nasty caveat. If you use an IDE such as PHPStorm or NetBeans, and then add a method like this to the User class:
public function foo() {
$this->profile->...
}
...bye bye auto-completion. This is the case even if you code to interfaces (the I in SOLID), using a pattern like this:
<?php
public class User {
public $profile;
public function __construct() {
$this->profile = new class implements UserProfileInterface {
// Some code here for user profile
}
}
}
?>
Unless your only calls to $this->profile are from the __construct() method (or whatever method $this->profile is defined in) then you won't get any sort of type hinting. Your property is essentially "hidden" to your IDE, making life very hard if you rely on your IDE for auto-completion, code smell sniffing, and refactoring.
Since PHP version 5.4 you can force create objects with private constructor through reflection. It can be used to simulate Java nested classes. Example code:
class OuterClass {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function forkInnerObject($name) {
$class = new ReflectionClass('InnerClass');
$constructor = $class->getConstructor();
$constructor->setAccessible(true);
$innerObject = $class->newInstanceWithoutConstructor(); // This method appeared in PHP 5.4
$constructor->invoke($innerObject, $this, $name);
return $innerObject;
}
}
class InnerClass {
private $parentObject;
private $name;
private function __construct(OuterClass $parentObject, $name) {
$this->parentObject = $parentObject;
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function getParent() {
return $this->parentObject;
}
}
$outerObject = new OuterClass('This is an outer object');
//$innerObject = new InnerClass($outerObject, 'You cannot do it');
$innerObject = $outerObject->forkInnerObject('This is an inner object');
echo $innerObject->getName() . "\n";
echo $innerObject->getParent()->getName() . "\n";
You can't do it in PHP. PHP supports "include", but you can't even do that inside of a class definition. Not a lot of great options here.
This doesn't answer your question directly, but you may be interested in "Namespaces", a terribly ugly\syntax\hacked\on\top\of PHP OOP:
http://www.php.net/manual/en/language.namespaces.rationale.php
I think I wrote an elegant solution to this problem by using namespaces. In my case, the inner class does not need to know his parent class (like the static inner class in Java). As an example I made a class called 'User' and a subclass called 'Type', used as a reference for the user types (ADMIN, OTHERS) in my example. Regards.
User.php (User class file)
<?php
namespace
{
class User
{
private $type;
public function getType(){ return $this->type;}
public function setType($type){ $this->type = $type;}
}
}
namespace User
{
class Type
{
const ADMIN = 0;
const OTHERS = 1;
}
}
?>
Using.php (An example of how to call the 'subclass')
<?php
require_once("User.php");
//calling a subclass reference:
echo "Value of user type Admin: ".User\Type::ADMIN;
?>
You can, like this, in PHP 7:
class User{
public $id;
public $name;
public $password;
public $Profile;
public $History; /* (optional declaration, if it isn't public) */
public function __construct($id,$name,$password){
$this->id=$id;
$this->name=$name;
$this->name=$name;
$this->Profile=(object)[
'get'=>function(){
return 'Name: '.$this->name.''.(($this->History->get)());
}
];
$this->History=(object)[
'get'=>function(){
return ' History: '.(($this->History->track)());
}
,'track'=>function(){
return (lcg_value()>0.5?'good':'bad');
}
];
}
}
echo ((new User(0,'Lior','nyh'))->Profile->get)();
It is waiting for voting as RFC
https://wiki.php.net/rfc/anonymous_classes
This page keeps coming up in my Internet searches on this subject so figured I should chime in even though this is an 8-year old post. The documentation for PHP5 demonstrates that anonymous classes can be defined within a class method. The object created can extend, implement, and even use other classes, interfaces, and traits. Consider the following OOP paradigm of factory object production. Similar to what #e-i-pi pointed out ...
class Factory {
/**
* Method to manufacture an inner-class object.
*
* #param string $args Arguments to be passed to
* the inner-class constructor.
*/
static function manufacture_object($args) {
/**
* Here's the definition of the inner-class.
*/
return new class($args) {
static $remembers = 'Nothing';
private $args;
function __construct($args) {
$this->$args = $args;
}
function says() {
return $this->args;
}
};
}
}
/**
* Create an inner-class object and have it do its thing.
*/
$mort = Factory::manufacture_object("Hello World!");
echo $mort->says(); // Echoes "Hello World!"
The objects are one-off, so one would expect the static values of the objects returned would not bind from one instance to another. After all, the anonymous class is unique from one object to another. However, late static binding works as one would otherwise expect from a nested class.
$mort = Factory::manufacture_object("I can remember that.");
$mort2 = Factory::manufacture_object("I'll live vicariously through you.");
$mort::$remembers = 'Something';
echo $mort2::$remembers; // Echoes "Something"
So, there you go: inner/nested classes and creation of their objects with static functionality has been possible since September 22, 2013 (right about the time this question was asked).
Put each class into separate files and "require" them.
User.php
<?php
class User {
public $userid;
public $username;
private $password;
public $profile;
public $history;
public function __construct() {
require_once('UserProfile.php');
require_once('UserHistory.php');
$this->profile = new UserProfile();
$this->history = new UserHistory();
}
}
?>
UserProfile.php
<?php
class UserProfile
{
// Some code here
}
?>
UserHistory.php
<?php
class UserHistory
{
// Some code here
}
?>