what's meaning of the source code "new CI;" in pyrocms? - php

I want to research the source code of pyrocms, and when I read the Base.php, I can't understand the following code
new CI;
the file is system/cms/libraries/Base.php
My problems are
why there has no a variable name, like $CI = new CI;
why it can be used as CI::$APP->config->item('controller_suffix') in it's sub class MX_Controller since there does not have variable name?
Thank you very much!!!

This object isn't stored in a variable because it seems we don't need to manipulate it. On the other hand, look at its constructor: it does a lot of things (since it also calls the constructor of CI_Controller, which in turns loads a Loader and initializer it, ....)
So, we don't build it in order to manipulate it afterwards, but in order to run the code in its constructor.
We can use CI::$APP-> whatever because $APP is a static member, hence it doesn't require to have an instance of CI to be manipulated

Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static cannot be accessed with an instantiated class object (though a static method can).
see statics on php.net

Related

How to make static class in PHP

I need static class (object) to store a global variable value. I'm new in PHP but i have experience in other language that have OOP concept like in Java. In Java i can make static variable and can call anywhere i want. But how to do same in PHP?
I use CodeIgniter framework , before i try this i try using session to store but i want to use another way like above. can anyone help me?
Can i do like this ?
static class myClass{
public static myVar = "";
}
Because you mentioned framework Codeigniter and use of session I assume that you need to use this in multiple controller and views.
So I there is also another way which works bit different than property of class but more similar than session (except changed value won't affect on another page).
So Use Constant.
Define it in
application > config > constant.php
page. There are many constant defined in that page, using exact same syntax you can define your values and you can use it very easily to any where.
just like if you define SITE_NAME constant in constant.php as
defined('SITE_NAME') OR define('SITE_NAME', "My Example Site");
After that you can use it anywhere in any controller, view or model of your Codeigniter, What you need to do is just echo it
<?php echo SITE_NAME; //only SITE_NAME not $SITE_NAME ?>
I hope it is what you want, if not sorry for my misunderstanding.
You can have a static-like class in PHP. But you don't have an app-cycle in PHP. This means you won't get a real static (or singleton) in your whole application.
If you shouldn't be able to instantiate a class then it should be abstract and define its methods as static. However, somebody could just subclass the class and make it non-abstract. If you don't want that to be a possibility either then the class should be abstract final.
If you do this, you can call methods directly on the class in question with ClassName::methodName() syntax. Do bear in mind that classes written like this can't make use of $this because it is only valid for an object instance. If you need the class to maintain state then you will have to define a static variable and use it with self:: or static:: syntax.
abstract final class SomeClass
{
private static $var = "";
public static function setVar($newVal)
{
self::$var = (string) $newVal;
}
public static function getVar()
{
return self::$var;
}
}
A word of caution on doing this though, use of abstract classes/methods can very easily lead to tightly coupled code which is bad for a number of reasons.
For example, if you write a class that calls the methods of an abstract class directly by any means other than inheriting from the abstract class, then it will be impossible to unit test that class in isolation. It will always require your abstract class to be part of the test suite too, which means it's more difficult to determine whether a test failure has been caused by a fault in the class under test or in the abstract class it's depending on.
What's more, if the abstract class you're depending on serves as an accessor for a data source, then you also will not be able to mock the class during tests. Mocking is a very powerful way of verifying the correctness of a class without having to rely on the environment that the class is running in. for example, you can mock a database access class with a compatible object that always returns the same data from an array instead of hitting an actual database. This means that you can guarantee that when you run a test it will run with data in a state that you have full control over. If you access a database via an abstract class's methods then you can't replace that for testing and suddenly you may end up with a test suite that might succeed or fail depending on the state of the database at the time you run the test. Even worse, if your tests involve writing to the database then you could potentially corrupt your data source when running tests.

PHP: Calling class functions from within a class

Starting a new PHP project and deciding that after a few years of PHP development, I'm thinking I should really start using PHP classes. I'm used to classes in the C++ world, so there's a few things I'm not quite sure about when porting this knowledge over to PHP.
In C++, you can automatically access any class variables without a prefix, in PHP, it appears that you need to prefix all such accesses (variables and function) with this->. I know what this is (or at least I think so, a pointer to the current class instance), but I'm not sure whether its required or preferred, or if there is any alternatives. My class will be using other functions within the same class (ie, itself) fairly heavily, so having to type this-> every time is going to get time consuming quite quickly.
The classes themselves are likely to be singletons, so I'm not sure whether to actually use a class, or just prefix the functions with an identifier.
It is required that you reference the object to which the member belongs in order to access the member.
Every method call or property access is prefixed with $variable-> - $this is a magic variable that refers to the current object instance. Its use is not optional.
This is (amongst other reasons) because not every function in PHP is a method, there are also global functions. If you reference a function without associating it with an object, it is assumed to be a global function.
As a side note, you should avoid the use of singletons in PHP - there is no performance/memory gain to be found from using them because each concurrently executing script is garden-walled into its own memory space.
The "pointer" (->) != C++ pointer.
$this means the current class and instance. All variables are accessed by using $this->variable; or $this->function();.
Static variables, and functions can be accessed using self::$variable or self::function()
Outside the class instance, you must indicate the class instance: $foo->variable; or $foo->function();
As far as I know, there is no way to access public/private/static/constant variables inside the class without using $this-> or self::
In reference to using an object of functions... up to you. Are you planning on expanding the code later to add more functions? Are all the functions somewhat related? If they are singleton functions, there is no harm in just writing a function instead of a class. It really just depends on what you are trying to accomplish.
Yes, you do have to use $this when accessing class method's or variables.
You need to remember that PHP doesn't require that variables be declared, so image the following situation:
<?
class A {
public $a = 'Hello World!';
function hello() {
$a = 'hello';
echo $a;
}
}
$object = new A();
echo $object->hello();
$a would be local scope and $this->a would be the class variable.

To store as a class parameter or normal php variable

I am new to OO concepts in PHP. I have a class called MY_ controller which is my base class. All classes extend this class. I am using MVC architecture. I am using caching in my system now. So i load the cache variable in the constructor of my base class. I use normal php variable like $cacheVariable in my function to store the value from cache. I was wondering if it would serve any help if i store it as a class parameter and use like $this->cacheVariable? In each function i get cache value like $this->cache->get('cacheVariable'); will it help if i get value from $this->cacheVariable
If you want to be able to use $cacheVariable anywhere else besides your constructor you'll want to use $this
public function __construct() {
//...
$this->cacheVariable = $this->cache->get('cacheVariable');
//...
}
Also remember, if you want your children classes to inherit this variable from your base class you will need to set it as either public or protected. If it's private children will not inherit it.
When you say "class variable" I assume you are referring to a property (property of an instance=. Note the difference:
if you have a class, say MyClassA, then in your scripts you will instantiate that class using the operator new (depending on your PHP version you can use a different constructor syntax it changed since PHP-5.3.0):
<?php
class MY_controller{
public $cacheVariable;
// constructor
function MY_controller($aValue){
// constructor code which loads cacheVariable, for example with parameter
$this->cacheVariable = $aValue;
}
public function someFunction(){
//... some code, then access the property
$cv = $this->cacheVariable;
}
}
$aController = new MY_controller(42);
?>
As you inherit from MY_controller, every instance of that class, will have access to cacheVariable through $this->cacheVariable.
The important thing I wanted to clarify is that it is an instance property, not a class one. For further reference on OOP in PHP, refer to the properties section in PHP's OOP manual and the inheritance section.
When you instantiate only one instances of your controller (derived from your main controller), its a conceivable solution.
In my opinion the better idea is getting variable directly from cache service everywhere you want in your class and don't keep it as a class property. The reason is simple: let's say value of some key from cache will be changed (or expires) in the other place than your class. If you have this value as class property you need to keeping eye on it every time you access this value but if you retrieving it from cache you just don't care (because the cache cares if value of some key doesn't changed or expired).

How does CodeIgniters dynamic loading class work?

I am trying to build my own simple MVC framework, mainly for educational purposes than anything else, I have used CodeIgniter in the past which has provided most of the inspiration for the features I would like to incorporate into my framework.
I would like to build a loader class like CodeIgniters, but I can't understand how CI loads the classes as if they are properties of the calling class i.e
class Random_Controller{
function __construct(){
$this->load->helper('some_class');
$this->some_class->do_something();
/*
How does CI load some_class as if it were a property of Random_Controller?
I can understand using something like $$class_name = new $class_name();
Or $$this->class_name = new $class_name();
But how can the dynamically named object be used with $this->?
*/
}
}
Hopefully that makes sense...
I am always surprised at how simple things appear with the right explanation. One more question though.
If $load is a reference to an instance of load class, and a record of all loaded classes is kept in an array, we are essentially doing:
$this->loaded_classes[$key]->do_something()?
So how does CI resolve the array to a variable name? I have seen some PHP magic methods that are called when variables do not exist or methods do not exist, would this be done in conjuction with these magic methods? In other words if the $this->some_class property does not exist we search for an element in the array with that key?
If that makes sense..
Uhm, well, let's start with this: the CI_Controller super class; it's the one all controllers extends, and acts as the CI superobject all the $this refer to.
CI_Controller acts as a singleton, and during initializing it calls a function, load_class() (you can find in core/common.php) which works as an autoloader : inside a static array ($_classes) it assignes as index the class name, and as value the class instance:
$_classes[$class] = new $name();
Then the companion is_loaded() function (in the same file) registers in an array all the function loaded, and is used to check later if the class has already been instantiated or not.
Ci_Controller assigns then to its $load property an instance of the Loader class (core/loader.php, by using the above mechanism)
$this->load =& load_class('Loader', 'core');
which, in turn, is responsibile for loading all other resources using its own methods: helper(),library(),model() and so on. Have a look at the source for all details, hope you got the picture though
To clarify as per your comment:
$load = new Loader();
$load->helper('helper');
would be the same as:
$this->load->helper('helper'),
as $this->load contains an instance (by reference) of the Loader class.
Then how the helper(),library(),etc methods of the Loader class work would be too much to write here, and beside you can open up the Loader.php file and have a look by yourself.

How to explain 'this' keyword in a best and simple way?

I am using 'this' keyword for a long time. But when someone asks me to explain it, I am confused that how to explain it. I know that I can use this in a method of class to access any variable and method of the same class.
class MyClass{
function MyMethod1(){
echo "Hello World";
}
function MyMethod2(){
$this->MyMethod1();
}
}
Is it a object of a class that we don't need to initialise and can be used only within the class or anything else. How to explain?
Thanks
A class is a mold for an object: it specifies how the object looks like (variables) and what it can do (functions).
If you instanciate a class: you create an object. If you create the class, you can use "this" to refer to the object itsself. This is why you can't set the "this", because it's related to the object. It's a special, read-only variable.
this references the current object instance of a class.
this is an implicitly parameter passed to the methods of a class: it is scoped to a method and allows access to all of the object's members.
Like their name suggests, instance methods operate on instances of a class. How do they know which one to operate on? That's what the this parameter is for.
When you invoke an instance method, you're really invisibly passing in an extra parameter: the object to invoke it on. For example, when you have this:
class Basket {
public function a() {
$this-> ...;
// ...
}
// ...
}
and you call $some_basket->a(), behind the scenes you're actually calling something like Basket::a($some_basket). Now a() knows which Basket you want to work with. That special parameter is what this refers to: the current object you're dealing with.
short:
$this gives you access to the object variables (and methods) Edit: within the class :) Edit 2: (but not in static methods of the class) :D
Several people have explained it in similar terms, but thought I'd add that when speaking to people unfamiliar with object oriented programming, I explain that the class definition is the blueprint, as for a house, and "this" is the actual house you're working with at that moment. There might be other houses that look exactly the same, but this is the specific object (house).
A class is a template or a 'die' for an object.
Lets use the classic 'bicycle' example. There are many huffy bikes out there. However, we have created one bike, and we can use the 'this' keyword to refer to 'this' bike.
In more a more technical sense, a class is a template for an object that will be instantiated. At run time, after an object has been instantiated, or had an instance of itself created, we can then use the keyword 'this' internally to refer to the instance that runs that method.

Categories