How do I make a variable that is created within a class function available outside of that class function?
For instance, the constructor of my main class creates an instance of the logging class. I want this $log variable to be available in other classes (using the global keyword) I would assume.
Is this possible?
You can use static.
class Main
{
static private $log;
public function __construct()
{
self::$log = new Log();
}
static public function getLog()
{
return self::$log;
}
}
Now you can get access to $log everywhere using
Main::getLog();
Using a global would defeat the purpose of OOP. OOP is meant to alleviate dependence and provide code containment for modular use.
You are simply approaching your application design wrong, instead, design ease of access to the logging instance. That is; instantiate your logging class and store the instance somewhere that's accessible (by design) by other classes that depend on it. A sort of "registry".
Related
In PHP, I'm developing an app that needs a singular instance to store and share data. I also have a couple of static classes that need to get and modify the data within the instance.
I would like to avoid global variables if it can be done, but I really don't know how to make the static classes and their methods access the instance.
Or is it a good idea to have one global instance as a global variable
$app = new App;
and then the static classes can use that global variable?
class Util {
public static function method() {
global $app;
$app->property = 'something new';
}
}
It seems like not the best idea. But without using singletons, I really don't see another way. I've also looked at dependency injection, but I couldn't find a way to make them work with static classes.
EDIT: I might not articulate myself clearly. It's not for saving data as a cache. It's runtime data.
I am trying to develop an object oriented PHP application in which whole php application will be extending from MyApplicationBase base class. But the problems is I want to create only single instance of MyApplicationBase. Below is the code which explains what I mean
class MyApplicationBase{
static $called=0;
public var $db;
function __construct()
{
self::$called++;
echo "<pre>MyApplicationBase Created ".self::$called." times</pre>";
$this->db=new DatabaseWrapper();
}
}
class ApplicationSecurity extends MyApplicationBase{
function is_logged_in()
{
$res=$this->db->query("user check db query goes here");
return ($res)?true:false;
}
//..... other methods related to ApplicationSecurity class
}
class ApplicationBusinessLogic extends MyApplicationBase{
// business logic methods here which may use base class vars like $db
// this may also use instance of ApplicationSecurity class
}
class ApplicationTemplating extends MyApplicationBase{
protected function outputHeader()
{
require_once('path/to/themes/header.php');
}
protected function outputSidebar()
{
require_once('path/to/themes/siderbar.php');
}
protected function outputMainbody()
{
require_once('path/to/themes/mainbody.php');
$app=new ApplicationBusinessLogic();
$app->initiate();
}
protected function outputFooter()
{
require_once('path/to/themes/footer.php');
}
public function outputTemplate()
{
$this->outputHeader();
$this->outputSidebar();
$this->outputMainbody();
$this->outputFooter();
}
}
//index.php file code starts here--------
$myPhpApplication = new ApplicationTemplating();
$myPhpApplication->outputTemplate();
My goal is when I create instance of my application then It only call the single instance of "MyApplicationBase" class instead of calling it multiple times. Please do tell me how can I achieve this. I am google for 5 hours but unable to find any solution yet.
I am trying to develop an object oriented PHP application in which whole php application will be extending from MyApplicationBase base class.
As PHP has single inheritance, this is by far the most worst idea to do object oriented PHP programming.
But the problems is I want to create only single instance of MyApplicationBase.
As every class is a MyApplicationBase you actually don't want that because it would mean you could instantiate exactly one class in your whole application.
What you're probably looking for is some kind of ApplicationClass which you pass along and of which just a single instance exists.
This would at least allow you in the future to throw such a "block in road" away more easily then if you would have got extended from there.
In any case you should program against an ApplicationInterface instead of an ApplicationClass to make this throwing away - as it will be necessary - easier.
The best thing for sure would be to not do anything in that direction and only write code you need in the first place.
To only write code you need, you need to develop test-driven. Why not start with that if you want to do object oriented programming?
Well I suppose that you want to avoid multiple connections to the database in this case. Solution is simple with Dependency injection, just initialize your database connection outside of MyApplicationBase class and then pass it as a constructor parameter (beware of constuctor hell though). Like this:
class MyApplicationBase{
static $called=0;
public $db;
function __construct($db)
{
self::$called++;
echo "<pre>MyApplicationBase Created ".self::$called." times</pre>";
$this->db= $d;
}
}
$db = new DatabaseWrapper();
$templating = new ApplicationTemplating($db);
$security = new ApplicationSecurity($db);
You could also take a look at some framework, they usually come with some dependency injection capabilities.
I've been programming in PHP for several years and I've only just recently begun to look at object oriented code. Now I understand classes and such:
class Myclass {
public function __construct() {
}
}
and all that good stuff... I also understand creating functions and calling in my index.php:
$someVar = new Myclass;
One thing I've been trying to understand, being that i've recently looked at codeigniter and I like one thing about it and want to try and accomplish the same thing without actually using codeigniter.
in code igniter they have the variable $this appear to be their class variable. But by using that, you're able to call from multiple classes all at once.. such as:
$this->load->module(); which is in one class file..
$this->db->query(); which is in another class file.
I've searched google for the last few days trying to figure out how to do this same thing where each class would have the correlation between them all allowing me to run $this->class_name->function_name in my projects instead of creating a new variable for each class or for the sake of a clean index file, having every function in a single class file.
Any information (aside from buy this book - as that isn't an option for me) is greatly appreciated and I will thank you now (and will probably thank you again later just for good measure).
I've been reading you and Phil's comments. First off, you can't use $this on index.php. $this can only be used in the context of an object. So you could do,
$someVar = new Myclass;
...
$someVar->db->something();
...instead.
I'm not entirely sure what you mean by "read classes," but you can assign members to MyClass exactly as Phil indicates:
class MyClass {
private $inj;
function __construct(Injected $inj) {
$this->injected = $inj;
}
}
Note that the private $inj declaration is not mandatory, but skipping it is dangerous. Any non-declared members added are automatically public, and this can potentially screw with you if you rely on magical get. I would declare the properties you need.
Finally, you either need to include all class definitions you will use, use a function like load_class(), or use autoloading. If Injected above is not a declared class, you will get an error when trying to create one. load_class() almost certainly includes the class definition somehow.
The load and db references are class properties which are themselves other objects with public module() and query() methods respectively. For example
class MyClass
{
/**
* #var CI_DB
*/
private $db;
/**
* #var Loader
*/
private $load;
public function __construct(CI_DB $db, Loader $load)
{
$this->db = $db;
$this->load = $load;
// PHP also allows you to add arbitrary object properties
// that receive a "public" visibility
// Please note, this is not a good practice
$this->foo = new Foo;
}
public function someMethod()
{
$this->load->module();
$this->db->query();
// You can also use foo even though it is not defined
// in the class properties
$this->foo->something();
}
}
See http://www.php.net/manual/en/language.oop5.properties.php
Adding the foo property like we did is dangerous. Because it receives the public visibility, it may be altered externally to the class.
$class = new MyClass($db, $load);
$class->foo = new Bar;
$class->someMethod(); // will break if Bar does not contain a something() method
This article is similar to my needs, but I'm more curious about a specific solution to it, and if it's a good or bad idea to do it. Sharing objects between PHP classes
Say, like in the link above, I have an object I want to pass to multiple classes, say a $db object.
Instead of using dependency injection and passing it to each method's constructor, is it ever a good idea to let all the classes extend a Base class, that stores the $db object as a property?
For example:
abstract class Base {
protected static $_db;
public function setDatabase( Database $db ) {
$this->_db = $db;
}
public function getDatabase() {
return $this->_db;
}
}
class SomeClass extends Base {
public function doStuff() {
$result = $this->getDatabase()->query(.....);
}
}
Which would mean all classes that extend Base need not worry about grabbing/checking/setting the $db themselves, as they'd already have that object as a property as soon as the class is defined.
I know dependency injection is the usual way to go, but is this ever a viable solution?
Thanks!
You still have to set the db on each instance of the class - setting it on one instance doesnt set it on all instances... unless of course its a static property.
That is perfectly fine. I have used it before and never ran into any issues.
First of all I'm very new to OOP and I'm struggling big time. I have a question about the current design of my application and inheritance.
I have a bootstrapper file which initiates all my core classes, after including them, like this:
$security = new Security;
$error_handler = new ErrorHandler;
$application = new Application;
$mysql = new MySQL;
$template = new Template;
$user = new User;
I load the Security and ErrorHandler class first because the Application class needs them first (throw custom 404 errors, make GET variables safe etc). Now all classes extend the Application class, but I can't seem to call any data in any class from a child or parent class.
I read that I need to call the constructor of the parent class first to use any data. That's not really sexy and usefull in my eyes and I don't really see the use of using extends then.
Should I change the design? Or how could I use data from one to another class? I already tried composition but that ended up in a nightmare because I couldn't use any data of different child classes at all.
This is a weird set-up anyhow. You definitely should NOT be using some bootstrapper functionality to preload your classes, especially if certain classes have finite dependencies on other classes. What would be a bit better is this:
Your Security and ErrorHandler classes should use either static methods to allow their functionality to be used without declaring the class OR they should be created as a class var of the Application class.
class Security {
// can be invoked anywhere using Security::somefunction('blah');
public static somefunction($somevar) { ... }
}
OR
require_once('security.php');
require_once('errorhandler.php');
class Application {
public $security;
public $errorHandler;
public function __construct() {
$this->security = new Security;
$this->errorHandler = new ErrorHandler;
}
}
I'm not sure what you mean when you say that you can't access data from any class. Classes should naturally inherit any variables and functions that their parents have declared. So for example:
require_once('application.php');
class User extends Application {
public function throwError($message) {
return $this->errorHandler->somefunction($message);
}
}
Without expressly declaring $this->errorHandler from within the User class, this should still work, as the $errorHandler class var is declared in the Application class.
If you have a child-class that defines a __construct() method, and want its parent's __construct() method to be called, the __construct() method of the child class must call the parent's one.
That's the way it is in PHP ; that's what you must do ; not much of a choice.
As a reference, quoting the Constructors and Destructors section of the manual :
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.