I'm building an API service and have a parent class:
classAPI {
public responseCode = "";
public responseMessageLog ="";
function run{
// here I call my user auth class
$oUser = new classUser(...);
}
}
Inside my classUser I do a bunch of stuff and then write a bunch of variables: responseMessageLog (which is running log of where the script went) and responseCode (which is set to 0 or 1 or whatever depending on success or failure or warning).
I need to access my responseCode and responseMessageLog variables from within my User class and my parent API class, but I don't really want to be passing these variables into each child class and then passing them back. I would like it that when I update the variable in the child class it updates everywhere in all my class.... kind of like a global variable would... but I know that's not a good idea.
How have others stopped passing variables down the rabbit trail of classes.
in this class I
Passing dependencies isn't a rabbit hole you want to avoid--it makes for more testable code. However, you don't need to pass every property, you can pass the parent object.
In your case just pass the classAPI object into the constructor of the classUser and in the constructor assign it to property. The classAPI properties are public so you can access them in an instance of classUser.
ClassAPI {
public $responseCode = "";
public $responseMessageLog ="";
public function run{
// here I call my user auth class
$oUser = new ClassUser($this, ...);
}
}
ClassUser {
public $myClassApi = null;
public function __construct(ClassAPI $myClassApi) {
$this->myClassApi = $myClassApi;
}
public function someFunction() {
echo $this->myClassApi->responseCode;
}
}
Added notes:
In case it comes up in another answer, don't use static properties to do what you're trying to do.
Capitalize your class names.
In production code I might add an initialization function in ClasUser instead passing the ClassAPI directly into the constructor.
Write what is best and why?
class Chat
{
private $_couleur;
private $_race;
function __construct($couleur, $race)
{
$this->_couleur = $couleur;
$this->_race = "$race";
}
public function getCouleur() {
return $this->_couleur;
}
}
Or
class Chat
{
function __construct($couleur, $race)
{
$this->_couleur = $couleur;
$this->_race = "$race";
}
public function getCouleur() {
return $this->_couleur;
}
}
Because $this->_couleur is initialized when the class is instancied, so declare the property directly in the class is useless, isn't ?
Declaring the variables at the top of your class is a very good practice, because it makes it clear to anyone that reads your code which properties the class has private and which properties the class has public.
In the second example your variables will be public because they're dynamically generated.
When your constructor would be much bigger it is a pain in the ass as developer to find out where your variables are introduced.
It is also good to set default values (if they are always the same) to the variables in the class as opposed to the constructor. It makes your code more readable and understandable.
First block of code is better from the second, But one thing in first block.
Objects of the same type will have access to each others private and protected members even though they are not the same instances. This is because the implementation specific details are already known when inside those objects.
This code collected from php.net
<?php
class Test
{
private $foo;
public function __construct($foo)
{
$this->foo = $foo;
}
private function bar()
{
echo 'Accessed the private method.';
}
public function baz(Test $other)
{
// We can change the private property:
$other->foo = 'hello';
var_dump($other->foo);
// We can also call the private method:
$other->bar();
}
}
$test = new Test('test');
$test->baz(new Test('other'));
?>
Output:
string(5) "hello"
Accessed the private method.
The first one is better. You are actually declaring your variables as private, giving them a meaningful scope. The second version is more error-prone.
Just wanted to add one simple benefit of declaring class properties: Any good IDE will parse and build a symbol table out of your declared class properties. So if you are writing a class and start typing $this->, a list of your declared properties will show up so you can easily select the one you want to use. If you create variables in your constructor without declaring them, your IDE won't be able to see them.
I've run into a problem and I'm not sure if this is just normal behaviour or if I wrote something wrong. I have a method in my base class that applies a global filter to a given class by way of creating a proxy for all new instances of that particular class. The way I planned to go about it is as follows:
Attach static $global_filter (the proxy) to the class I want to be filtered, which extends the base class object
Via my loading mechanism, return the proxy instead of the actual class upon new instantiations (which will mask method calls and apply filters accordingly)
However, I am getting stuck in step 1 and it seems that when I try to assign static $global_filter to the descendent class I want filtered, my base class object also gets the same assignment, which breaks everything else that extends from it.
Please see below for relevant code:
class object {
public static $global_filter;
public function _filterGlobal($class, $method, $callback) {
if ( !is_object($class::$global_filter) ) {
$class::$global_filter = new filterable(null);
# Replace the object being called with the new proxy.
}
var_dump($class);
var_dump($class::$global_filter); // `filterable`
var_dump(\core\blueprint\object::$global_filter); // Returns same as line above
die();
return $class::$global_filter->_add($method, $callback);
}
}
Both $class::$global_filter and \core\blueprint\object::$global_filter (the base class) are returning same instance. Whereas I expected object::$global_filter to be null.
I'm not using late static binding in order to preserve consistency (both single-object filters and global filters are called much in the same way non-statically).
This question seems relevant
Any help will be much appreciated :)
Edit, full example
This would be a concrete class, which extends model which extends object
<?php
use core\blueprint\model;
class modelMock extends model {
protected $schema = array();
public function method($test) {
return $test;
}
}
This would be another object (e.g a controller), which extends object aswell. It applies a filter to all new instances of model
<?php
use core\blueprint\object;
class objectMock extends object {
public function applyFilters() {
$this->_filterGlobal('core\blueprint\model', 'method', function($self, $chain) {
$chain->params[0] = 'new param'; // adjust the paramters
return $chain->next();
});
}
}
when I try to assign static $global_filter to the descendent class I want filtered, my base class object also gets the same assignment
Yes, indeed this happens. A static property in essence is a global variable, constrained within the class's namespace. Running into problems with global variables is often an indication you're not using the best solution.
To solve your problem, you could make the filter a (non-static) property:
$class->$filter = new Whatever();
But as always, there's more roads that lead to Rome, and I would advise you to look for alterative ways to do it.
I don't know if this is a help for you:
class a {
public static $type;
public static function setType($class, $newType) {
$class::$type = $newType;
var_dump($class::$type);
}
}
class b {
public static $type = 'myType';
}
var_dump(b::$type);
a::setType('b', 'yourType');
var_dump(a::$type);
May be you have not defined the static property to the concrete class.
Thanks everyone for you help, I spent some time on it this morning and managed to solve my problem. It's a bit of a workaround but here's how it goes:
public function _filterGlobal($class, $method, $callback) {
if ( !is_object($class::$global_filter[$class]) ) {
$class::$global_filter[$class] = new filterable(null);
# Replace the object being called with the new proxy.
}
return $class::$global_filter[$class]->_add($method, $callback);
}
So basically in order to get unique static variables working in child classes without having to explicitly define them, you can use an array that stores the child's class name as a key and then access these variables via a getter.
I have a database class, which an instance is declared in the main index.php as
$db = new Database();
Is there a way for the $db variable to be globally recognized in all other classes without having to declare
global $db;
in the constructor of each class?
No. You have to declare Global $db in the constructor of every class.
or you can use the Global array: $_GLOBALS['vars'];
The only way to get around this is to use a static class to wrap it, called the Singleton Method (See Here for an explanation). But this is very bad practice.
class myClass
{
static $class = false;
static function get_connection()
{
if(self::$class == false)
{
self::$class = new myClass;
}
else
{
return self::$class;
}
}
// Then create regular class functions.
}
The singleton method was created to make sure there was only one instance of any class. But, because people use it as a way to shortcut globalling, it becomes known as lazy/bad programming.
StackOverflow Knowledge
How to Avoid Using PHP Global Objects
Share Variables Between Functions in PHP Without Using Globals
Making a Global Variable Accessible For Every Function inside a Class
Global or Singleton for Database Connection
I do it a little different. I usually have a global application object (App). Within that object I do some basic initialization like creating my db objects, caching objects, etc.
I also have a global function that returns the App object....thus (application object definition not shown):
define('APPLICATION_ID', 'myApplication');
${APPLICATION_ID} = new App;
function app() {
return $GLOBALS[APPLICATION_ID];
}
So then I can use something like the following anywhere in any code to reference objects within the global object:
app()->db->read($statement);
app()->cache->get($cacheKey);
app()->debug->set($message);
app()->user->getInfo();
It's not perfect but I find it to make things easier in many circumstances.
you could use
$GLOBALS['db']->doStuff();
or alternatively using some kind of singleton access method
Database::getInstance()->doStuff();
Why not create a class that contains the global $db; in it's constructor, then extend all other classes from this?
You could use a Registry class to store and retrieve your Database instance.
class Registry
{
protected static $_data = array();
public static function set($key, $value)
{
self::$_data[$key] = $value;
}
public static function get($key, $default = null)
{
if (array_key_exists($key, self::$_data)) {
return self::$_data[$key];
}
return $default;
}
}
Registry::set('db', new Database());
$db = Registry::get('db');
I have been noticing __construct a lot with classes. I did a little reading and surfing the web, but I couldn't find an explanation I could understand. I am just beginning with OOP.
I was wondering if someone could give me a general idea of what it is, and then a simple example of how it is used with PHP?
__construct was introduced in PHP5 and it is the right way to define your, well, constructors (in PHP4 you used the name of the class for a constructor).
You are not required to define a constructor in your class, but if you wish to pass any parameters on object construction then you need one.
An example could go like this:
class Database {
protected $userName;
protected $password;
protected $dbName;
public function __construct ( $UserName, $Password, $DbName ) {
$this->userName = $UserName;
$this->password = $Password;
$this->dbName = $DbName;
}
}
// and you would use this as:
$db = new Database ( 'user_name', 'password', 'database_name' );
Everything else is explained in the PHP manual: click here
__construct() is the method name for the constructor. The constructor is called on an object after it has been created, and is a good place to put initialisation code, etc.
class Person {
public function __construct() {
// Code called for each new Person we create
}
}
$person = new Person();
A constructor can accept parameters in the normal manner, which are passed when the object is created, e.g.
class Person {
public $name = '';
public function __construct( $name ) {
$this->name = $name;
}
}
$person = new Person( "Joe" );
echo $person->name;
Unlike some other languages (e.g. Java), PHP doesn't support overloading the constructor (that is, having multiple constructors which accept different parameters). You can achieve this effect using static methods.
Note: I retrieved this from the log of the (at time of this writing) accepted answer.
It's to declare the constructor.
class Cat
{
function __construct()
{
echo 'meow';
}
}
Constructors are invoked whenever a new instance of the class is created, in this case, the constructor will be invoked with this line:
$cat = new Cat();
In older PHP versions, the constructor could also be declared using the class name, for ex:
class Cat
{
function Cat()
{
echo 'meow';
}
}
I think this is important to the understanding of the purpose of the constructor.
Even after reading the responses here it took me a few minutes to realise and here is the reason.
I have gotten into a habit of explicitly coding everything that is initiated or occurs. In other words this would be my cat class and how I would call it.
class_cat.php
class cat {
function speak() {
return "meow";
}
}
somepage.php
include('class_cat.php');
mycat = new cat;
$speak = cat->speak();
echo $speak;
Where in #Logan Serman's given "class cat" examples it is assumed that every time you create a new object of class "cat" you want the cat to "meow" rather than waiting for you to call the function to make it meow.
In this way my mind was thinking explicitly where the constructor method uses implicity and this made it hard to understand at first.
The constructor is a method which is automatically called on class instantiation. Which means the contents of a constructor are processed without separate method calls. The contents of a the class keyword parenthesis are passed to the constructor method.
The __construct method is used to pass in parameters when you first create an object--this is called 'defining a constructor method', and is a common thing to do.
However, constructors are optional--so if you don't want to pass any parameters at object construction time, you don't need it.
So:
// Create a new class, and include a __construct method
class Task {
public $title;
public $description;
public function __construct($title, $description){
$this->title = $title;
$this->description = $description;
}
}
// Create a new object, passing in a $title and $description
$task = new Task('Learn OOP','This is a description');
// Try it and see
var_dump($task->title, $task->description);
For more details on what a constructor is, see the manual.
I Hope this Help:
<?php
// The code below creates the class
class Person {
// Creating some properties (variables tied to an object)
public $isAlive = true;
public $firstname;
public $lastname;
public $age;
// Assigning the values
public function __construct($firstname, $lastname, $age) {
$this->firstname = $firstname;
$this->lastname = $lastname;
$this->age = $age;
}
// Creating a method (function tied to an object)
public function greet() {
return "Hello, my name is " . $this->firstname . " " . $this->lastname . ". Nice to meet you! :-)";
}
}
// Creating a new person called "boring 12345", who is 12345 years old ;-)
$me = new Person('boring', '12345', 12345);
// Printing out, what the greet method returns
echo $me->greet();
?>
For More Information You need to Go to codecademy.com
class Person{
private $fname;
private $lname;
public function __construct($fname,$lname){
$this->fname = $fname;
$this->lname = $lname;
}
}
$objPerson1 = new Person('john','smith');
__construct is always called when creating new objects or they are invoked when initialization takes place.it is suitable for any initialization that the object may need before it is used. __construct method is the first method executed in class.
class Test
{
function __construct($value1,$value2)
{
echo "Inside Construct";
echo $this->value1;
echo $this->value2;
}
}
//
$testObject = new Test('abc','123');
I believe that function __construct () {...} is a piece of code that can be reused again and again in substitution for TheActualFunctionName () {...}.
If you change the CLASS Name you do not have to change within the code because the generic __construct refers always to the actual class name...whatever it is.
You code less...or?
__construct is a method for initializing of new object before it is used.
http://php.net/manual/en/language.oop5.decon.php#object.construct
Note: Parent constructors are not called implicitly if the child class defines a constructor. In order to run a parent constructor, a call to parent::__construct() within the child constructor is required. If the child does not define a constructor then it may be inherited from the parent class just like a normal class method (if it was not declared as private).
__construct simply initiates a class. Suppose you have the following code;
Class Person {
function __construct() {
echo 'Hello';
}
}
$person = new Person();
//the result 'Hello' will be shown.
We did not create another function to echo the word 'Hello'. It simply shows that the keyword __construct is quite useful in initiating a class or an object.
A constructor allows you to initialize an object's properties upon creation of the object.
If you create a __construct() function, PHP will automatically call this function when you create an object from a class.
https://www.w3schools.com/php/php_oop_constructor.asp
Let me explain __construct() without first using the method ... One thing to know about __construct() is that it is an inbuilt function, well let me call it method in PHP. Just as we have print_r() for procedural, the __construct() is an inbuilt for OOP.
That being said, let's explore why you should use this function called __construct().
/*=======Class without __construct()========*/
class ThaddLawItSolution
{
public $description;
public $url;
public $ourServices;
/*===Let us initialize a value to our property via the method set_name()==== */
public function setName($anything,$anythingYouChoose,$anythingAgainYouChoose)
{
$this->description=$anything;
$this->url=$anythingYouChoose;
$this->ourServices=$anythingAgainYouChoose;
}
/*===Let us now display it on our browser peacefully without stress===*/
public function displayOnBrowser()
{
echo "$this->description is a technological company in Nigeria and our domain name is actually $this->url.Please contact us today for our services:$this->ourServices";
}
}
//Creating an object of the class ThaddLawItSolution
$project=new ThaddLawItSolution;
//=======Assigning Values to those properties via the method created====//
$project->setName("Thaddlaw IT Solution", "https://www.thaddlaw.com", "Please view our website");
//===========Let us now display it on the browser=======
$project->displayOnBrowser();
__construct() makes life for you very easy, imaging the time it took me to assigning values to those properties via that method. From the code above, I created an object which is first and then assign values to the properties which is second before finally showing it on the browser. But using __construct() while creating an object i.e. $project= new ThaddLawItSolution; you would do what you did for assigning values to that method immediately while creating the object, i.e.
$project=new ThaddLawItSolution("Thaddlaw IT Solution", "https://www.thaddlaw.com","Please view our website");
//===Let's now use __constructor=====
Just remove that method called setName and put __construct(); and when creating an object, you assign the values at once. That is the point behind the whole __construct() method. But note that this is an inbuilt method or function