Smarty allows to access object properties using this syntax in templates:
{$object->property}
But (If I understood this correctly) this is possible only if property visibility is public, otherwise it seems that Smarty won't be able to access it.
In Java I'm used to create objects that have private properties, and I usually read/write these properties in business logic using getters and setters. But, even if I create an object with a private property, I'm able to access it in a jsp using expression language:
${object.property}
This won't happen in Smarty templates, since private properties cannot be accessed this way. So I would have to use a syntax like:
{$object->getProperty()}
Why is that? Why doesn't Smarty get round the problem as jsp EL does?
Reading and writing to private members of object from the outside violates OOP encapsulation principle. If you mark a member of class as private, you expect that no one except the code in the class (or friend functions) can access it.
Keeping as few public members as possible reduces dependencies between different code modules, making your application more flexible. If you can access private member of, let's say your model, your template must know internal implementation of the model. Making changes to your model will cost you a lot of time, because you would need to change your templates as well.
If you have getter and setter of your private member, you are free to change it as you like, template will know nothing.
Related
I am using cakephp 3.x
I made this observation. Functions in controllers and tables are declared as public. Functions in entities are declared as protected. Why can't entities functions be declared as public as well?
This sounds like you have no idea when and why you use the visibility scope. See this question "What is the difference between public, private, and protected?" as well.
In fact nothing prevents you from declaring a public method in an entity, try it. Nothing prevents you from using protected and private in other classes as well. But use them where it makes sense architecture wise. Also entities already have public methods. I suggest you to read the chapter about entities in the book, it explains in detail how entities work, what they are and what they're thought for and what you can do with them.
Entities represent data, the data is accessed through the properties or like an array because the object implements ArrayAccess. To access virtual properties (again, read the chapter) the accessors and mutators are used, which are in fact protected. These methods get called when you try to access a non existing property, see the get() method. They're protected because direct access to them is not desired, it would break the way the entities work. Data is thought to be accessed only through the properties or the get() method so that all entities everywhere work the same.
In well written code the visibility scope usually has a reason. But I've seen bad code where people made things private like crazy without reason, which effectively prevents you from altering the objects behaviour by inheriting them. I haven't checked but I'm pretty sure you won't find a private method in the framework because it is thought to be extended.
Bottom line: Analzye the code and get an understanding of why something is protected if you like to know it. It will be for a different reason from case to case.
I'm currently doing a tutorial on PHP and it has me create a class Person which might represent a user on a website.
There are two public fields ($firstname and $lastname) and the tutorial has me access them using $some_person->firstname.
I know in Java we would most likely want to make these fields private and use getters and setters to access them. Should I apply this same practice to PHP?
Yes - PHP5+ supports public/protected/private methods in classes. You don't need to design getters/setters but if the class grows/adds functionality it'll be safer than letting people call the properties directly.
Yes, in general properties should be made protected or private and getters and setters offered. This will allow you to add in type hints in the setter signature or validation in the setter body, which will make it harder for bad data to slip into properties unnoticed. I tend to recommend this approach even if "you don't need it now" - you may do so later.
The argument against public properties in PHP is just the same as it is in Java: it opens up the "black box" of the class to the outside world, and starts to break down the encapsulation that classes are meant to offer in the first place.
Classes are usually meant to be extended, which has a bearing on whether properties should be protected or private. If child classes are trusted (e.g. part of the same codebase) the developer may be happy to allow direct access to the property, in which case it can be protected. However, if the code is intended for release (e.g. as a F/OSS library) then there's an argument for forcing child classes use the getter and setter methods, in which case the properties should be private.
PHP would let calls to private methods as long as they come from instances of the same class.
This is how the PHP docs explains it:
Objects of the same type will have access to each others private and protected members even though they are not the same instances. This is because the implementation specific details are already known when inside those objects.
Doesn't this break encapsulation? How does the fact that implementation specific details are known justify it?
p.s. Are there other (object oriented) languages that do this?
This is true for most languages, in java you can do it too,
this is because the object is from the same instance, it "knows" all the properties same instances have
As an answer to the post scriptum, Delphi (so-called "object pascal") and Lazarus ("free pascal") both allow access to the private properties only in the same unit that the class implementation is coded. So you can insert two different classes inside one unit and they have access to each other's private properties.
It is not allowed if two classes are placed in different units (let's say it's something like a namespace in PHP).
As an answer to "Doesn't this break encapsulation?":
Although the Encapsulation principle in OOP definition is a bit vague. The way I understand it is it keeps private data and logic in the bounds of a class.
Encapsulation is used to hide the values or state of a structured data object inside a class, preventing unauthorized parties direct access to them.
I don't know if this behaviour of classes in PHP, Java and other languages is good or bad, but I don't think it breaks the Encapsulation of the classes.
I am learning about modules online and it seems like modules in js and classes in php are very similar. Both group functions together for easier to understand coding. Functions can be declared in both and made public or private. How are they similar in use and how are they different?
Javascript's modules provides some nice features like encapsulation, the private state and even inheritance from other modules. While they provide some of the features of classes, as in PHP, they are not. They try to build on the existing Javascript functonality to emulate classes, hence why the confusion. i.e. they are built to look and feel like classes.
Javascript's modules are instances of an anonymous function assigned to a variable. Therefore they have all the features of a function where their code is executed top to bottom, they have and sometimes use a return statement (in PHP classes no statements can be run directly apart from field definition and assignment) and they even have access to global variables. In PHP, on the other hand a class, or rather it's methods, cannot access a variable that is not in the class itself. In order to access global variables a class method or static function has to explicitly call the variable i.e global $a inorder to import it. In js modules, all global vars are accessible but sometimes one chooses to explicity import them for neater code (function(a){})(imported);
Another important issue is data abstraction. While js modules provide private states for the fields, PHP's classes, just like C++, java, python etc, provide more security to the properties. It allows for base classes using the abstract class and interface keywords whereby class methods and attributes are only defined or structured but not used.
PHP classes also have constructors and destructors, that are called when the class object is initialized and on the last mention used to destroy the object. Granted, you can create functions in modules to run when you want, in PHP on the other hand, functions in the method are only executed when they are called either by the object, the class or other functions.
In classes there are static functions, these can be called without even having an object of the class and run independent of objects, on the other hand in js, everything is an object; which defeats the point of static functions.
They are similar in that: both have inheritance, where you can extend an existing module with a new one, and in PHP you can use extends to inherit from a parent class. They both have private data states preventing external access, they both group and package data and methods, and both are awesome when utilized properly.
I have used object oriented more in java, where a private member cannot be accessed from outsite the class, protected extending access to child classes, default access extending access to packages and public to every class.
How does this work in PHP when using MVC frameworks( I am using CodeIgniter)? Does it mean all methods in models which I will be accessing from Controllers have to be public?
It means the same thing.
There are no friend classes in php, so you cant break private just because you are using a MVC pattern. Note this is true in Java as well.
This isnt really CI specific... but yes. check out: http://www.php.net/manual/en/language.oop5.visibility.php for more info on php method/property visibility.