As it is right now, i have my class system to be embedded in my core class. So i call my classes as such:
$cms->userClass->function();
But this means that for every function i have in my userClass, i constantly need to add:
global $cms;
To be able to access the database class as such:
$cms->db->function();
Is there any way to set a global for the whole class, instead of having to define it at the start of every function?
Instead of using functions everywhere, if you build your own classes and put those functions within the classes you could set a single property within the class and access everything by $this->var....
$class = new MyClass($cms);
echo $class->cms; //doesn't work cause it's private
class MyClass () {
private $cms; //private so it's only accessible within this class
function __construct ($cms) {
$this->cms = $cms;
}
//all your functions here can use $this->cms
function myFunction () {
echo $this->cms->func(); //this will work
}
}
I don't think there is global for a class.
However, a couple of alternatives:
have a reference to the global $cms variable in a class, so:
private $cmsref;
function __construct(){
global $cms;
$this->cmsref = &$cms; // $this->cmsref will be a reference to $cms now
}
use the superglobal $_GLOBALS:
function foo(){
// to access $cms:
$_GLOBALS["cms"];
}
Related
I'm developing a club membership register web application and I am a fairly newbie when it comes to oop. The problem I'm having is that I would need to call a function outside a class, but I know you can't do that in PHP and I need to solve it somehow.
This code will demonstrate what my problem is:
members.php
class member {
private $id;
private $member_num;
private $name;
...
...
public function __construct() {
$a = func_get_args();
$i = func_num_args();
if (method_exists($this,$f='__construct'.$i)) {
call_user_func_array(array($this,$f),$a);
}
}
private function __construct1($f_id) { // Construct object by id-number
// Code to retrieve the data from database
}
I've written the code for database actions in a separate file called database_functions.php, but I can't include that file inside a class. What I need to know is how can I access those functions without having to write them again inside the class? (I have written applications before with VB.Net and in it I can use functions of the current project inside classes.)
You can extend a class to another class to access parent class functions and properties in subclass. Functions declared private cannot be accessed like that. You can also pass object of another class to to one class as an argument to the constructor.
if you have a class name parent :
class parent{
// properties and methods
}
Then you can access its functions if you extend it to your class :
class child extends parent{
// code
}
OR
$parent = new parent();
$child = new child($parent);
Then in child class you can use :
function __construct($parent) {
$this->connection = $parent;
}
Then within other functions in child class you can access the parent class methods using
$parent->connection->function_name()
you can use require_once() with exact path of that class after that you should use the object of the included class and function name for calling the function of outer class.
if(file_exists($class_path))
{
require_once($class_path);
$cl_obj = new name_of_class();
$outer_class_result = call_user_func_array(array($cl_obj,$function_name),$parametrs);
}
If you have a main file that calls different files (via include or require), then you can use any function that will exist in global namespace just fine in that class, provided the function you call will always exist in global namespace.
At the top of your class file, for instance, you could call another file with use of require_once. (Just to be sure you never include the same file twice, it's always good to use include_once and require_once.)
The other options is to wrap the other functions you have inside another class, provided that it makes sense. Class A could then hold a field with a class B object and call B's functions as it pleases.
class classA {
private $BInstance;
function __construct($b) {
$this->BInstance = $b;
}
function some_call($input) {
if($this->valid_input($input)) {
$this->BInstance->transform($input);
}
}
}
The benefit of this is that everything is abstracted in classes. Once you're outside of the class, all you have to know is what methods (functions) you can use of a class and you won't have to worry about the implementation details. A direct advantage of this is that you don't have to pass the same parameter to same functions all the time, say, if you need a database handler to execute SQL code within a function. A class could just hold such an instance and you won't have to repeat the same parameter all the time.
An additional advantage is that your global namespace won't be polluted with specific functions.
I'm not sure if you include the file which defined the functions you want.
I tried this with my symfony preject and it works well.
The test.php contains a function.
<?php
function double_number($value)
{
return $value*2;
}
?>
and I include it in the Model:
include(__DIR__.'/test.php');
class HomeModel
{
...
public function __construct()
{
$this->preExecute();
echo double_number(5);
exit;
}
...
}
and it output whith 10.
Maybe you need the include the file I think.
In my opinion here is one solution :-
Make your file('database_functions.php') a class containing all your functions. Like..
class mydbcls{
public function function_1(){}
public function function_2(){}
public function function_3(){}
//......
public function function_n(){}
}
Now when you are writing your class which is named as "member", write it in such a way that it extends your mydbcls.
class member extends mydbcls{
private $id;
private $member_num;
private $name;
...
...
public function __construct() {
$a = func_get_args();
$i = func_num_args();
if (method_exists($this,$f='__construct'.$i)) {
call_user_func_array(array($this,$f),$a);
}
}
private function __construct1($f_id) { // Construct object by id-number
// Code to retrieve the data from database
// Now you can access your database functions in this way
// $this->function_1();
}
now you can access your db functions this way
$this->function_1();
I want to know what is the scope that function who is out of class. Is it private, public or protected ?
function abc {
//code here
}
class xyz {
function car () {
// code here
}
}
Now what is the abc function scop ?
Please help me
Functions outside any class are global an can be called from anywhere. The same with variables.. just remember to use the global for the variables...
e.g
<?php
function abc() { }
$foo = 'bar';
class SomeClass {
public function tada(){
global $foo;
abc();
echo 'foo and '.$foo;
}
}
?>
functions are defined at a global level ; so, you don't need to do anything to use them from a method of your class.
For more informations, see the function page in the manual, which states (quoting) :
All functions and classes in PHP have the global scope - they can be called outside a function even if they were defined inside and vice versa.
If a "function" is defined inside a class, it's not called a "function" anymore, even if it is still the function that is used : it is called a "method"
Methods can be used statically :
MyClass::myMethod();
Or Dynamically :
$obj = new MyClass();
$obj->myMethod();
Depending on whether they were defined as static or not.
function abc {
//code here
}
This is a public function because function scope mainly in class and in your case abc
not inside a class so it behave as a public function
public scope to make that variable/function available from anywhere, other classes and
instances of the object.
private scope when you want your variable/function to be visible in its own class only.
protected scope when you want to make your variable/function visible in all classes that extend current class including the parent class.
reference What is the difference between public, private, and protected?
Let's say I have the following class:
class SQLMapper{
static find_user_by_id($id){
//sql logic here, using the $_DATABASE global to make a connection
}
}
I could simply call:
global $_DATABASE;
at the top of my function, but I don't want to do that for ALL of my static methods. Is there a way to get a static variable inside my class to reference the global $_DATABASE array?
EDIT: I can't assign it in the constructor, since this is all static, and the constructor is never called.
You can use the super-global array $_GLOBALS to access your $_DATABASE variable. For example:
query( $GLOBALS['_DATABASE'], 'some query' );
Alternatively, write a static function that returns the contents of that variable:
class SQLMapper
{
static function getDatabase()
{
global $_DATABASE;
return $_DATABASE;
}
static function find_user_by_id($id)
{
query( self::getDatabase(), 'some query' );
}
}
If it hurts, its likely that you're
doing it wrong.
First off, without seeing more of your code its impossible to provide a more concrete solution, but I would strongly recommend that you consider rearranging your class structure so that your static functions (it sounds like you've got a long list of them to implement) become non-static.
In essence, you should consider accessing an instantiated instance of SQLMapper and then calling the appropriate method from the instance. Using this paradigm, you could just instantiate a class level property for $_DATABASE which can then be freely referenced by all methods in the class.
For example:
class SQLMapper {
private $_db;
public function __construct()
{
global $_DATABASE;
$this->_db = $_DATABASE;
}
public function find_user_by_id($id) {
$sql = "Select * from User WHERE Id = ?";
$stmt = $this->_db->prepare($sql, $id);
return $stmt->execute();
}
}
With that said, using globals is generally a sign of poor code quality so I would also suggest that you consider taking a more object-oriented approach to your current design and look for tried and true methods for eliminating globals from your application altogether.
I'm not so sure I understand what you mean, sorry, but can you try using the static keyword?
This should be obvious, but I'm getting a bit confused about PHP variable scope.
I have a variable inside a Constructor, which I want to use later in a function in the same class. My current method is this:
<?php
class Log(){
function Log(){
$_ENV['access'] = true;
}
function test(){
$access = $ENV['access'];
}
}
?>
Is there a better way to do this than abusing environment variables? Thanks.
You could use a class variable, which has a context of... a class :
(Example for PHP 5, of course ; I've re-written a few things so your code is more PHP5-compliant)
class Log {
// Declaration of the propery
protected $_myVar;
public function __construct() {
// The property is accessed via $this->nameOfTheProperty :
$this->_myVar = true;
}
public function test() {
// Once the property has been set in the constructor, it keeps its value for the whole object :
$access = $this->_myVar;
}
}
You should take a look at :
The "Classes and Objects" section of the PHP manual
And, for this specific question, the sub-section Properties
Globals are considered harmful. If this is an outside dependency, pass it through the constructor and save it inside a property for later use. If you need this to be set only during the call to test, you might want to consider making it an argument to that method.
You could use the global keyword:
class Log{
protected $access;
function Log(){
global $access;
$this->access = &$access;
}
}
But you really should be passing the variable in the constructor:
class Log{
protected $access;
function Log($access){
$this->access = &$access;
}
//...Then you have access to the access variable throughout the class:
function test(){
echo $this->access;
}
}
I have a variable on the global scope that is named ${SYSTEM}, where SYSTEM is a defined constant. I've got a lot of classes with functions that need to have access to this variable and I'm finding it annoying declaring global ${SYSTEM}; every single time.
I tried declaring a class variable: public ${SYSTEM} = $GLOBALS[SYSTEM]; but this results in a syntax error which is weird because I have another class that declares class variables in this manner and seems to work fine. The only thing I can think of is that the constant isn't being recognised.
I have managed to pull this off with a constructor but I'm looking for a simpler solution before resorting to that.
EDIT
The global ${SYSTEM} variable is an array with a lot of other child arrays in it. Unfortunately there doesn't seem to be a way to get around using a constructor...
Ok, hopefully I've got the gist of what you're trying to achieve
<?php
// the global array you want to access
$GLOBALS['uname'] = array('kernel-name' => 'Linux', 'kernel-release' => '2.6.27-11-generic', 'machine' => 'i686');
// the defined constant used to reference the global var
define(_SYSTEM_, 'uname');
class Foo {
// a method where you'd liked to access the global var
public function bar() {
print_r($this->{_SYSTEM_});
}
// the magic happens here using php5 overloading
public function __get($d) {
return $GLOBALS[$d];
}
}
$foo = new Foo;
$foo->bar();
?>
This is how I access things globally without global.
class exampleGetInstance
{
private static $instance;
public $value1;
public $value2;
private function initialize()
{
$this->value1 = 'test value';
$this->value2 = 'test value2';
}
public function getInstance()
{
if (!isset(self::$instance))
{
$class = __CLASS__;
self::$instance = new $class();
self::$instance->initialize();
}
return self::$instance;
}
}
$myInstance = exampleGetInstance::getInstance();
echo $myInstance->value1;
$myInstance is now a reference to the instance of exampleGetInstance class.
Fixed formatting
You could use a constructor like this:
class Myclass {
public $classvar;
function Myclass() {
$this->classvar = $GLOBALS[SYSTEM];
}
}
EDIT: Thanks for pointing out the typo, Peter!
This works for array too. If assignment is not desired, taking the reference also works:
$this->classvar =& $GLOBALS[SYSTEM];
EDIT2: The following code was used to test this method and it worked on my system:
<?php
define('MYCONST', 'varname');
$varname = array("This is varname", "and array?");
class Myclass {
public $classvar;
function Myclass() {
$this->classvar =& $GLOBALS[MYCONST];
}
function printvar() {
echo $this->classvar[0];
echo $this->classvar[1];
}
};
$myobj = new Myclass;
$myobj->printvar();
?>
The direct specification of member variables can not contain any references to other variables (class {public $membervar = $outsidevar;} is invalid as well). Use a constructor instead.
However, as you are dealing with a constant, why don't you use php's constant or class constant facilities?
You're trying to do something really out-of-the-ordinary here, so you can expect it to be awkward. Working with globals is never pleasant, especially not with your dynamic name selection using SYSTEM constant. Personally I'd recommend you use $GLOBALS[SYSTEM] everywhere instead, or ...
$sys = $GLOBALS[SYSTEM];
... if you're going to use it alot.
You could also try the singleton pattern, although to some degree it is frowned upon in OOP circles, it is commonly referred to as the global variable of classes.
<?php
class Singleton {
// object instance
private static $instance;
// The protected construct prevents instantiating the class externally. The construct can be
// empty, or it can contain additional instructions...
protected function __construct() {
...
}
// The clone and wakeup methods prevents external instantiation of copies of the Singleton class,
// thus eliminating the possibility of duplicate objects. The methods can be empty, or
// can contain additional code (most probably generating error messages in response
// to attempts to call).
public function __clone() {
trigger_error('Clone is not allowed.', E_USER_ERROR);
}
public function __wakeup() {
trigger_error('Deserializing is not allowed.', E_USER_ERROR);
}
//This method must be static, and must return an instance of the object if the object
//does not already exist.
public static function getInstance() {
if (!self::$instance instanceof self) {
self::$instance = new self;
}
return self::$instance;
}
//One or more public methods that grant access to the Singleton object, and its private
//methods and properties via accessor methods.
public function GetSystemVar() {
...
}
}
//usage
Singleton::getInstance()->GetSystemVar();
?>
This example is slightly modified from wikipedia, but you can get the idea. Try googling the singleton pattern for more information
I'd say the first two things that stand out to me are:
You don't need the brackets around the variable name, you can simply do public $system or public $SYSTEM.
While PHP may not always require it it is standard practice to encapsulate non-numeric array indexes in single or double quotes in case the string you're using becomes a constant at some point.
This should be what you're looking for
class SomeClass {
public $system = $GLOBALS['system'];
}
You can also use class constants which would instead be
class SomeClass {
const SYSTEM = $GLOBALS['system'];
}
This can be referenced within the class with 'self::SYSTEM' and externally with 'SomeClass::SYSTEM'.