I found out that object constants in PHP always have public visibility so it is not possible to set them to protected or private like this:
<?php
class MyClass {
protected const constant = "this won't work";
}
?>
What's the explanation for this? I can't think of a good reason to force constants to be public.
That's a rather philosophical question, which is discussed in the comments for Class constants in the PHP Manual. The argument seems to be that Visibility identifies who has the right to change members, not who has the right to read them. Since constants cannot be changed, there is no point in having them support visibility when visibility is understood as access modifiers. If you follow that argumentation or go with the linked feature request below your question is up to you.
I can't think of a good reason to force constants to be public.
Well, constants are static definitions, bound to the class and not instantiated objects. They can be addressed only using classname::constname, and they cannot be altered. It stands to reason they are part of the blueprint of a class, and thus it doesn't really make sense to apply visibility rules to them.
That's just my rather subjective opinion, though. Interested to see whether anything based on hard OOP theory comes up.
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.
This question already has answers here:
Are private constants possible in PHP? [duplicate]
(4 answers)
Why doesn't PHP permit private const?
(2 answers)
Closed 8 years ago.
Why doesn't PHP permit private constants?
I am aware that there are workarounds, such as using a private static property instead.
However, from an OOP or software design perspective, what was the reasoning?
tl;tr
What was the reasoning to not implement private constants?
This is a good question.
Did they really consider this?
I don't know.
When searching through the PHP internals mailing list, i found nothing about this topic.
Unless a internal's member speaks up, we'll never know.
With regard to the history of the language - a bit 1:1 C method wrapping, some bits from Perl (regexp), some bits Java (oop) - it's possible that this idea popped up, while looking for new language features.
I would relate the concept of a "private constant" to VisualBasic or Java. I doubt that VB has a big or any influence on PHP. VB allows the definition of "private constants" in "Modules" - it's the default access scope. Visual Basic doesn't allow constants in Interfaces and Namespaces (but PHP does).
PHP might include some OOP concepts from Java, but there is one big difference: constants are variables in Java. Their access modifiers / visibility levels are: "public, private, final and static". A private constant declaration looks like this: "private static final String MYCONST = "My Constant"; It's OOP - end of story. PHP constant access feels more hackish compared to that - BUT it's more simple and you still have the workaround at hand.
The first comment in the PHP manual for Class Constants is:
It may seem obvious, but class constants are always publicly visible.
They cannot be made private or protected. I do not see it state that
in the docs anywhere.
Why is this obvious? "Why is a class constant public by default and not private?"
Maybe, it's a missing language feature, because not all class members can be hidden properly.
And he is right, when you come from Java or VB to PHP this question pops up.
Let's take a look at the PHP spec. The current state of implementation in PHP is: class constants are always public and static. So, again and again, thumbs up for Facebook for writing such detailed document: the author considered different visibility or access-control levels.
Let's take a look at interface, class, constant and visibility:
How does the concept "const" differ from "private static"?
The static variable can be changed, the constant cannot be changed.
You cannot assign the runtime value of a function to a const (const A = sprintf('foo %s', 'bar');), but to a private static var.
An interface might have constants - they cannot be overridden.
A class might have a constant - which might be overridden by a inheriting class/interface.
There is also an OOP pattern called "constant interface pattern" - it describes the use of an interface solely to define constants, and having classes implement that interface in order to achieve convenient syntactic access to those constants.
An interface is provided so you can describe a set of functions and then hide the final implementation of the functions in an implementing class. This allows you to change the implementation of the functions, without changing how you use it. Interfaces exist to expose an API.
And by defining constants in an interface and implementing the interface by a class, the constants become part of the API. In fact, you are leaking implementations details into the API. That's why some consider this being an anti-pattern, among them Joshua Bloch (Java).
Now, let's try to combine some concepts and see if they fit.
Let's pretend we try to avoid the critique from above, then you need to introduce a syntax, which allows qualified access to the constant, but hides the constant in the API. You could come up with "Access control" via visibility levels: "public, private, protected, friend, foe". The goal is to prevent the users of a package or class from depending on unnecessary details of the implementation of that package or class. It is all about hiding implementation details, right?
What about "private constants" in "interfaces"?
That would actually solve the critique from above, right?
But the combination of interface with "private", doesn't make sense. The concepts are contrary.
That's why interface do not allow "private" access/visibility-levels.
And a "private" constant in an "interface" would be mutually exclusive, too.
What about "private constants" in "classes"?
class a {
/*private*/ const k = 'Class private constant k from a';
}
class b extends a
{
const k = 'Overridden private constant a::k with Class constant k from b';
const k_a = parent::k;
// fatal error: self-referencing constant
#const k_selfref = self::k . ' + ' . self::k_selfref;
// fatal error: "static::" is not allowed in compile-time constants
#const k_staticref = static::k;
}
// direct static access would no longer work, if private
// you need an instance of the parent class or an inheriting class instance
echo a::k;
echo b::k;
echo b::k_a;
$obj_b = new b;
echo $obj_b::k;
echo $obj_b::k_a;
Is there a benefit?
The private constant in the class wouldn't be exposed in the API. This is good OOP.
The access to the parent constant from outside would be a class and/or inheritance access.
echo a::k, which now works - could respond with "Fatal error: Trying to access a private constant without a class instance or inheritance.".
(This might still work solely at compile-time, if there is no run-time value assignment to a const. But i'm not sure about this one.)
Are there caveats?
We would lose direct static access to constants.
Requiring that an instance of a class is created, just to access constants, is a waste of resources. Direct static access saves resources and is simple. If we introduce private, that's lost and the access would be bound to the instance.
A "private const" is implicitly a "private static const". The access operator is still "::".
A possible follow-up change would be the switch to implicitly non-static constants.
That's a BC break.
If you switch the default behavior to non-static, the access operator changes from "::" to "->".
This establishes a proper OOP object access to constants, which is comparable to Java's concept of "constants as variables with access level". This would work a bit like this: http://3v4l.org/UgEEm. The access operator changes to static, when the constant is declared as "public static const", right?
Is the benefit good enough to implement it?
I don't know. It's up for discussion.
I like both: the const static access, because it's dead simple and the concept of "constants as variables" and proper access levels.
After that's implemented, in order to save resources and keep going fast, everyone starts to (re-)declare "public static const", to drop the instance requirement and violate OOP ;)
And btw: i found an HHVM overflow, while experimenting with code of this answer.
Why doesn't PHP permit private constants?
In PHP constants are part of the interface and the interface is public, always (that's what an interface is for).
See as well PHP Interfaces.
I'm pretty sure this is the reason design-wise.
Regarding the comment under your question that someone wants to reduce the visibility of constants to change them later, I'd say this sounds more like a variable than a constant which does not change it's value. It's constant.
I am doing a class "Container" to hold all my model/service instances, the class is a singleton.
Consider the following code portion (from a CodeIgniter project):
public function getReviewModel()
{
static $loaded = false;
if (!$loaded)
{
$this->load->model('review_model');
$loaded = true;
}
return $this->review_model;
}
I am wondering if is still ok to use static inside method like this or should I use only class property (I mean about performance and coding standard) ?
In your example, nothing prevents the programmer to instanciate the class more than once (with dire results), so it is rather a confusing bit of code.
Static variables have their uses, be them local to a function or defined at class level.
Especially in PHP scripts, when the output is often a single piece of data that can conveniently be handled as a class defining only static properties and methods.
That would be a true, foolproof singleton class.
Since mistaking a static variable for a dynamic one is a common pitfall, I tend to favor static class variables to avoid the confusion (i.e. the self::$... syntax makes them stand out clearly).
General consensus as far as statics are concerned in PHP is: Avoid, if at all possible. And yes, 99% of the time, it is possible to avoid statics.
Singletons should be avoided 100% of the time. For reasons you can find here and virtually everywhere else on the web. Singletons are like communism: sounds like a nice idea, but when put in to practice, it turns out there's one or two things you didn't anticipate.
A Singletons' main purpouse is to retain state, but PHP itself is stateless, so come the next request, the singleton needs to be re-initialized anyway.
If I write getters like yours, I tend to create them in a lazy-load kind of way:
class Example
{
private $reviewModel = null;//create property
public function getReviewModel()
{
if ($this->reviewModel === null)
{//load once the method is called, the first time
$this->reviewModel = $this->load->model('review_model');
}
return $this->reviewModel;
}
}
This basically does the same thing, without using statics. Because I'm using a property, I still retain the instance, so if the getReviewModel method is called again, the load->model call is skipped, just as it would be using a static.
However, since you're asking about performance as well as coding standards: statics are marginally slower than instance properties: Each instance has a HashTable containing for its properties, and a pointer to its definition. Statics reside in the latter, because they are shared by all instances, therefore a static property requires extra lookup work:
instance -> HashTable -> property
instance -> definition -> HashTable -> property
This isn't the full story, check answer + links here, but basically: the route to a static propery is longer.
As for coding standards: They exist, though still unofficial, most major players subscribe to them, and so should you: PHP-FIG
Things like $this->_protectedProperty; don't comply with the PSR-2 standard, for example, which states, quite unequivocally:
Property names SHOULD NOT be prefixed with a single underscore to indicate protected or private visibility.
I just started to learn object oriented programming today and just by observation noticed that in all examples, member variables are private. Why is that usually the case?
// Class
class Building {
// Object variables/properties
private $number_of_floors = 5; // These buildings have 5 floors
private $color;
// Class constructor
public function __construct($paint) {
$this->color = $paint;
}
public function describe() {
printf('This building has %d floors. It is %s in color.',
$this->number_of_floors,
$this->color
);
}
}
Also, if you declare the member variable to be public, what is the syntax for accessing it outside of the class it was declared in?
And finally, do you have to prepend "public" or "private" to every variable and function inside a class?
EDIT: Thanks all for your answers, can anyone please confirm if you have to prepend "public" or "private" to every variable and function inside a class?
Thanks!
Rule of thumb is to try to hide information as much as possible, sharing it only when absolutely necessary.
Russian coders sometimes say Public Morozov at unnecessarily wide access modifiers, alluding to a story about improper information disclosure and about further punishment caused by that - Pavlik Morozov:
a 13-year old boy who denounced his father to the authorities and was in turn killed by his family...
Private variables can't be accessed from outside, that gives you control.
But if you put them Public then you can access it lke this
$your_object_instance->Your_variable
For example
$building = new Building();
echo $building->number_of_floors;
but you have to put your number_of_floors variable to public, if you want to access private member then you need to implement new method in Building class
public function getNumberOfFloors()
{
return $this->number_of_floors;
}
so your code should look like this
$building = new Building();
echo $building->getNumberofFloors();
It's to make the coding easier for you, and to make you less likely to make mistakes. The idea is that only the class can access its private variables, so no other classes elsewhere in your code can interfere and mess something up by changing the private variables in unexpected ways. Writing code like this, with a bunch of autonomous classes interacting through a small number of strictly controlled public methods, seems to be an easier way to code. Big projects are much easier to understand because they are broken up into bite sized chunks.
Making variables private keeps calling code from depending on the implementation details of your class so you can change the implementation afterward without breaking the calling code.
You can declare more than one variable on the same line and only use private or public once:
private $number_of_floors = 5, $color;
See also PHP docs' "Classes and Objects".
Senad's answer is correct in that it is good programming practice to make variables you do not want exterior methods to access private.
However, the reasoning for it in memory managed/garbage collected languages is that when you maintain a reference to an object, it is not able to be garbage collected, and can cause memory leaks.
Hope this helps!
I really dont know how to answer such question, but i describe u the best as per php manual
The visibility of a property or method can be defined by prefixing the
declaration with the keywords public, protected or private. Class
members declared public can be accessed everywhere. Members declared
protected can be accessed only within the class itself and by
inherited and parent classes. Members declared as private may only be
accessed by the class that defines the member.
Property Visibility
Class properties must be defined as public, private, or protected. If
declared using var, the property will be defined as public.
Methods declared without any explicit visibility keyword are defined as public.
for more information see Visibility
It's to prevent properties from being directly manipulated from the outside and possibly putting the object into an inconsistent state.
One of the fundamentals of OOP is that an object should be responsible for maintaining its own state and keeping it internally consistant, for example not allowing a property that's only meant to hold positive integers from being set to -343.239 or making sure an internal array is structured properly. A sure fire way of doing this is make it impossible for the values of properties to be directly set from the outside. By making the property private, you're preventing outside code from manipulating it directly, forcing it to go through a setter method that you have written for the job. This setter can do checks that the proposed change won't put the object into an inconsistent state and prevent any changes that would.
Most books and examples aimed at beginners tend to use very simple objects so it may not make sense as to why you need to go through all the private properties and getters and setters molarchy, but as the complexity of an object increases, the benefits become increasingly obvious. Unfortunately, complex objects are also not much good as teaching aids for beginners, so this point can be easily lost at first.
I'm writing a bunch of generic-but-related functions to be used by different objects. I want to group the functions, but am not sure if I should put them in a class or simply a flat library file.
Treating them like a class doesn't seem right, as there is no one kind of object that will use them and such a class containing all these functions may not necessarily have any properties.
Treating them as a flat library file seems too simple, for lack of a better word.
What is the best practice for this?
Check out namespaces:
http://www.php.net/manual/en/language.namespaces.rationale.php
Wrapping them in a useless class is a workaround implementation of the concept of a namespace. This concept allows you to avoid collisions with other functions in large projects or plugin/module type deployments.
EDIT
Stuck with PHP 5.2?
There's nothing wrong with using a separate file(s) to organize utility functions. Just be sure to document them with comments so you don't end up with bunchafunctions.php, a 20,000 file of procedural code of dubious purpose.
There's also nothing wrong with prefixes. Using prefixes is another way to organize like-purpose functions, but be sure to avoid these "pseudo-namespaces" already reserved by the language. Specifically, "__" is reserved as a prefix by PHP [reference]. To be extra careful, you can also wrap your function declarations in function_exists checks, if you're concerned about conflicting functions from other libraries:
if (!function_exists('myFunction')) {
function myFunction() {
//code
}
}
You can also re-consider your object structure, maybe these utility functions would be more appropriate as methods in a base class that all the other objects can extend. Take a look at inheritance: http://www.php.net/manual/en/language.oop5.inheritance.php. The base class pattern is a common and very useful one:
abstract class baseObject {
protected function doSomething () {
print 'foo bar';
}
public function getSomething () {
return 'bar foo';
}
}
class foo extends baseObject {
public function bar () {
$this->doSomething();
}
}
$myObject = new foo();
$myObject->bar();
echo $myObject->getSomething();
You can experiment with the above code here: http://codepad.org/neRtgkcQ
I would usually stick them in a class anyway and mark the methods static. You might call it a static class, even though PHP actually has no such thing (you can't put the static keyword in front of a class). It's still better than having the functions globally because you avoid possible naming conflicts. The class becomes a sort of namespace, but PHP also has its own namespace which may be better suited to your purpose.
You might even find later that there are indeed properties you can add, even if they too are static, such as lazy-loaded helper objects, cached information, etc.
I'd use classes with static methods in such case:
class Tools {
static public function myMethod() {
return 1*1;
}
}
echo Tools::myMethod();
EDIT
As already mentioned by Chris and yes123: if the hoster already runs PHP 5.3+, you should consider using namespace. I'd recommend a read of Matthew Weier O'Phinney's article Why PHP Namespaces Matter, if you're not sure if it's worth switching to namespaces.
EDIT
Even though the ones generalizing usage of static methods as "bad practice" or "nonsense" did not explain why they consider it to be as such - which imo would've been more constructive - they still made me rethinking and rereading.
The typical arguments will be, that static methods can create dependencies and because of that can make unit testing and class renaming impossible.
If unit testing isn't used at all (maybe programming for home/personal use, or low-budget projects, where no one is willing to pay the extra costs of unit testing implementations) this argument becomes obsolete, of course.
Even if unit testing is used, creation of static methods dependencies can be avoided by using $var::myMethod(). So you still could use mocks and rename the class...
Nevertheless I came to the conclusion that my answer is way too generalized.
I think I better should've wrote: It depends.
As this most likely would result in an open ended debate of pros and cons of all the different solutions technically possible, and of dozens of possible scenarios and environments, I'm not willing going into this.
I upvoted Chris' answer now. It already covers most technical possibilities and should serve you well.
Treating them as a class does give you the benefit of a namespace, though you could achieve the same thing by prefixing them like PHP does with the array_* functions. Since you don't have any properties, that basically implies that all your methods are static (as Class::method()). This isn't an uncommon practice in Java.
By using a class, you also have the ability, if necessary, to inherit from a parent class or interface. An example of this might be class constants defined for error codes your functions might return.
EDIT: If PHP 5.3+ is available, the Namespace feature is ideal. However, PHP versions still lag in a lot of hosts and servers, especially those running enterprise-stable Linux distributions.
I've seen it a few different ways, all have their warts but all worked for the particular project in which they were utilized.
one file with all of the functions
one file with each function as its own class
one massive utilities class with all of the methods
one utils.php file that includes files in utils folder with each
function in its own file
Yes, it's OK formally... As any class is methods + properties. But when you pack in class just some functions -- it`s become not ideal OOP. If you have bunch of functions, that groupped, but not used some class variables -- it' seems, that you have somewhere a design problem.
My current feeling here is "Huston, we have a problem".
If you use exactly functions, there one reason to wrap them in static class - autoloader.
Of course, it creates high coupling, and it's may to be bad for testing (not always), but... Simple functions are not better than static class in this case :) Same high coupling, etc.
In ideal OOP architecture, all functions will be methods of some objects. It's just utopia, but we should to build architecture as close as we can to ideal.
Writing a bunch of "generic-but-related" functions is usually bad idea. Most likely you don't see problem clear enough to create proper objects.
It is bad idea not because it is "not ideal OOP". It is not OOP at all.
"The base class pattern" brought by Chris is another bad idea - google for: "favor composition over inheritance".
"beeing extra careful" with function_exists('myFunction') is not but idea. It is a nightmare.
This kind of code is currently avoided even in modern javascript...