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.
Related
I could find the default visibility of a property and a method in the PHP manual. But i couldn't find any info regarding the class itself.
My guess is that it's public. But if someone could link to the part where this is written in the manual i would appreciate it.
Simply Put
Public. PHP doesn't support anything other than public classes.
Unlike Java/.NET/etc, there isn't any concept of packages, assemblies, internal or nested classes. Namespaces are essentially just syntactic sugar to avoid IncrediblyLongClassNames, and can't provide any actual changes to visibility.
The entire idea makes much less sense in a non-compiled language, since regardless of what scope you use, anyone could still just take your class and declare it in public.
A PHP 7 Proviso: Anonymous Classes
PHP 7 introduced the concept of anonymous classes*, allowing on-the-fly class definitions. As a very basic example:
<?php
$foo = new class {
public function hello($what)
{
echo 'Hello ', $what, PHP_EOL;
}
};
(new $foo)->hello('world');
# Hello world
Because these can be assigned to variables, they can be limited to the scope of that variable, and passed around like any other.
Unlike most language that allow anonymous classes, in PHP they do not inherit anything from the scope in which they are defined. The linked documentation has some examples of how to work around this, by defining the anonymous class as inheriting from a parent or passing in constructor arguments.
*Strictly speaking, under the hood they do have names, and as such if someone can run get_class() on an instance then they can then instantiate their own copy, since they aren't garbage collected.
PHP are always public "by default", but the most accurate answer here is that PHP classes don't have such concept anyway.
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
I need to have method to get something from a database, but I don't understand the difference between static and normal functions in PHP.
Example code
class Item {
public static function getDetail($arg) {
$detail = $this->findProductId($arg);
return $detail;
}
private function findProductId($id) {
//find product_id in database where id = $arg
//return detail of product
}
}
and function outside of a class
function getDetail($arg) {
$detail = findProductId($arg);
return $detail;
}
If I use $item = Item::getDetail(15); and $item = getDetail(15); — they're the same.
What is the difference between static and function outside of a class?
If they are difference, How to use static function and function outside of a class? (I'd appreciate a really simple example.)
What are the performance properties between static and function outside of a class? Which is better?
1) What is difference between static function and normal function
While they are functions, I'd prefer to call them methods of a given class. One is a static method and the other is an instance method.
Static Method: $item = Item::getDetail(15);
Instance Method: $item = getDetail(15);
(refer to FuzzyTree's correct syntax above in the comments, however.)
2) How to use static function and normal function (if you simple exemplify is good)
Static means you do not have to instantiate (declare an object reference). That is, you can simply use the method. So, in your example, while the answer may be the same, the way you called that method/function is different, as you noted above.
In Java, for example, you have the Math class. It does not require instantiation to use, and in fact you cannot that I know of because its constructor is private. You can simply use a method by referencing the class and the method name you wish to use,
Math.pow(d1, d2); //no instantiation needed
in PHP this might be,
MyClass::pow(d1,d2); //no instantiation needed
Java: when to use static methods
3) Ask performance between static function and normal function. Which is better?
Better is a matter of your design. If you have to create an object every time you want to do the power of a number that will create more memoryusage than simply using the class directly. I do not have benchmark proof, but it seem logical since you are not handling the method the same way in memory. I do not think it will matter in real world unless you are doing a lot of complicated actions.
Performance of static methods vs instance methods
might also interest you.
I'm assuming you're asking about the difference between a static method:
class Item {
public static function getDetail($arg){}
}
And a function written outside of a class definition:
function getDetail($arg){}
Static methods should be used over functions written outside of a class for organizational reasons. In an application with many files, having Item::getDetails($arg) will give a hint of where that function is defined. Also, having just a function written outside of a class runs the risk of name collision, if you start writing many functions outside classes.
Especially if you are writing in the OOP style, you should be using static methods over functions outside of class definitions, but I think even in general, using static methods is the better way to go.
The difference about static and non static functions is a big answer and we have to look at Object Oriented Programming (OOP) in general.
OOP in general, as you should know, is about Classes and Object, a class describe and creates objects based of it's description.
If you tell the class to contain the function "A" the object will have a callable function "A" who will have access to the objects parameters.
However if you tell the class to have a static function you tell the class to have a callable function WITHOUT instantiate an object.
Confusing? Can be at first and hard to understand why it's sometimes needed when you take your first OOP steps. Static functions is a good way to share info about classes without the need to make an object.
An analgy would be:
Take the class Car and the object BMW.
the objects functions is about THE BMW, a static functions is about cars in general.
As of performance, it's not about performance at all, it's about design patterns. So performance-wise there is nothing to gain if the functions is static or non static.
1.Entire difference is, you don't get $this supplied inside the static function. If you try to use $this, you'll get a Fatal error:
Static functions are associated with the class, not an instance of the class
and You will get an E_strict warning in the second case.
2.Now static calling of non-static methods works but is deprecated. so use normal function.
3.Technically speaking Static methods and variables are useful when you want to share
information between objects of a class, or want to represent something
that's related to the class itself, not any particular object.
For some reason, PHP allows you to call non-static and static methods
interchangeably,So performance wise or in whatever way you may say just use a normal function.Static is not going to help you at all
The difference between static and non static is that you can access a static method without having an instance of the class.
$item = getDetail(15); shouldn't work because detDetail is a method in a class and not a function.
Performance of Static Methods
There used to be a big penalty when calling a static method - but it's fixed in 5.4.0. See http://www.micro-optimization.com/global-function-vs-static-method
From what the other guy said, if it uses more memory one way versus the other it will absolutely cause a performance difference. If you're using so much memory to the point of going into GC, it can cause queuing of processes due to backup, due to gc and take the whole system down potentially if it's an enterprise system with thousands of concurrent users. It may depend on the scale of the application.
We should never be of the opinion that a change in memory utilization is "minor". It's never minor in big systems...
Generally when creating a PHP class I would do something as such
class Foo
{
public function Foo(){}
public function RandomFunction(){};
}
global $foo;
$foo = new Foo();
$foo->RandomFunction();
I have noticed that on the web people are frowning upon the global vars for classes but without it I would not be able to access the class inside other functions.
Now an alternative to this would be using static classes as such:
class Foo
{
static public function RandomFunction(){}
}
Foo::RandomFunction();
My Question is this, is this the best alternative to global vars for classes? Or is there a better way to go about it all together?
In good OO practice, if a class needs to access an instance of another class, you pass object in as a parameter and then access it's properties and methods from there.
If you have a well designed object model the code should be relatively clean and logical, however if you aren't planning on creating a strict OO application, you probably shouldn't worry about your classes being in global scope or not.
Think of your object like a bicycle. You own your bicycle, and can loan it to whomever you wish. They can use it and return it to you, and you will be able to keep track of who did what to your bike, and when.
If your bike is generally available to anyone in the world, however, your job of monitoring and controlling access to it will become exponentially more difficult. You will be hard-pressed to keep track of who is using your bike, when they are using it, and how they are (ab)using it.
Passing your objects (rather than declaring them globally) allows you to maintain stricter controls on your object and the data it contains.
I am trying to better understand basic concepts in OOP.
What are static and dynamic variables and methods in object-oriented programming?
What is, for instance, the difference between using $this vs. double colon (::)?
$this ($this->a_method())
Advantages: ?.
Disadvantages: ? ... "this" is not self-documenting as in: $this->method_from_an_extended_class().
Double colon (someclass::a_method())
Advantages: ?
Disadvantages: ?
"Static" and "dynamic" aren't the right descriptions for that.
-> indicates a instance functions or instance data, meaning that the function or data has an implicit $this reference. To put it another way you're referring to the function or variable within a particular object.
:: indicates a class function or class variable. This is very similar to a global function or variable in that there is no implicit $this reference. All instance of that class share that function or variable.
"Dynamic" would be a more accurate description for, say, PHP overloading where you can "dynamically" create variables, for example, using the magic methods __get() and __set() (which are called when you try to access a property that can't be found; you can overload these methods to essentially pretend the requested member exists).
Quoting the static page in the PHP manual :
Declaring class properties or methods
as static makes them accessible
without needing an instantiation of
the class. A property declared as
static can not be accessed with an
instantiated class object (though a
static method can).
Also note that when declaring a property as static, there will be only one version of that property for the whole script : static methods/properties "act at the class level rather than at the instance level" (quoting wikipedia).
About advantages / disadvantages, it's a bit hard to answer clearly, as those are just not the same...
The question is : what do you need ?
If you have an object that contains data, and want methods to deal with that data, you'll use dynamic properties and methods.
On the other hand, if you just want to use a class as container for methods that deal with external data (ie, not internal to the class), you'll probably use static methods.
For instance, I am sometimes using static methods as wrappers to libraries that don't export an Oriented-Object API : it allows me to call one class::method, instead of several functions.
Some would say an "advantage" of static methods is that you don't need to instanciate the class to use them -- that is true ; but it also means that you don't get objects, with methods working on them ; well : as I said, using static or not depends on what you need.
Oh, I almost forgot : if you are willing to use unit-testing, you might find out that static methods are not easy to test ; for instance, see Static Methods are Death to Testability.
And static properties (same with singleton and registry design patterns, which rely on static properties/methods) kind of imply "global state", like "global variables" -- which some don't quite like ^^