In my ZF 1.11 application I'm storing my translator in registry like this:
Zend_Registry::set('Zend_Translate', $translator);
So in my view scripts I can access the translator this way:
$this->translate('abc');
Is there any clever way to be able to use this call instead:
$this->_('abc');
Using $this->translate clutters the views, and lot's of people are used to seeing _() anyway.
Whereas I generally agree with the notion that function/method names should be meaningful, I also agree that the _() for translations is a widely used standard and therefore acceptable.
You can do this by adding wrappers to your intermediate layers. For example the following would make the method available to all your controllers derived from MyProject_Controller_Action:
class MyProject_Controller_Action extends Zend_Controller_Action
{
protected $translator;
public function init()
{
$this->translator = Zend_Registry::get('Zend_Translate');
}
/**
* Translator wrapper
*
* #param string $string The string to be translated
* #return string $translated The translated string
*/
protected function _($string)
{
$translated = $this->translator->translate($string);
return $translated;
}
}
Of course the same can be done with Zend_View.
Disclaimer: It is not the best practice to clutter your code with direct calls to the registry. Actually it's an anti-pattern which should be replaced by DI. Zend Framework 2 will make it much easier for us to avoid the registry. This code could be improved by actually injecting the translation object into the class via constructor.
No, not that I know of. There are several implicit issues related to that anyway. First, you should always give functions (and variables for that matter) meaningful names. That said, __() is not a meaningful name at all. Quite the opposite, in fact, it has no meaning. Second of all, it is considered best practice to prefix only private and protected functions (and, again, variables for that matter) with an underscore.
Finally, with the way zend view helpers work, you would pretty much have to sorta "trick" the system into locating your view helper if it was named __(). You would have to name it something like Zend_View_Helper___ and that wouldn't work. Not to mention, that would entail having to name your file __.php.
I suppose you could name your helper Zend_View_Helper_T, in which case you could translate stuff using $this->t($string); (I tested this and it works), but again you should always use meaningful names.
Edit
Having not realized that you wanted to call this from within the controller until now, I decided to revise my answer and give a little feedback about the comment I received from the down voter..
It's hard to recommend that you create a wrapper class for Zend_Controller_Action in which to create a function _() for the following reason:
Because regardless it being an "accepted standard" or not, I
reiterate that that all methods and variables should have a
meaningful name. I must assert this because I am a firm believer in
following explicit coding standards (as opposed to those "hearsay"
or "recently-adopted" practices that don't directly correspond to a
known - and thereby trusted - paradigm). That said, should PEAR, or
even Zend, decide to adopt such a radical change some day, I will
resign my disposition. NOTE: It could be argued that credible
companies like Drupal and their self-proclaimed best practices could
be considered explicit coding standards but I disagree. Why? Because
PEAR is...well...it's PEAR. And Zend is "The PHP Company." It's hard
to get more credible than that. If anyone disagrees with that last
statement please state why or correct me instead of down voting. Regardless, standards
are merely a suggestion not required; therefore, they should be treated as
such. So, I guess as long as you're following some standard then that's good! These
are not rules after all.
Nevertheless, markus' solution was good other than the function name (for reasons stated previously). The only thing I would change is the call to Zend_Registry::get() in the _() function. If you plan to call that function as much as you alluded to, then something like this might work better:
class MyProject_Controller_Action extends Zend_Controller_Action
{
/**
* the translator object
* #var Zend_Translate
*/
protected $_translator;
public function init()
{
$this->_translator = Zend_Registry::get('Zend_Translate');
}
/**
* note my new method name, you don't have to use it but I still
* recommend it. the name is just a suggestion, if you prefer something
* like _translate() or _trnslte() then by all means (although I don't
* recommend abbreviations unless they're super obvious I guess).
*/
protected function _trans($string)
{
return $this->_translator->translate((string) $string);
}
}
Related
I have classes with larges methods name that are called too many times.
Example:
/**
* This class do awesome things.
*/
class AwesomeClass {
/**
* Do something awesome.
*/
public function doSomethingAwesome()
{
//Do something awesome
}
}
Now, I call the method:
$awesomeInstance->doSomethingAwesome();
The method name is large and is typed to many times. For prevent misspelling, I created a shortcut method:
/**
* Shortcut of doSomethingAwesome()
*/
public function dsa()
{
return $this->doSomethingAwesome();
}
And calling method:
$awesomeInstance->dsa();
Is this a bad practice? How afect the performance?
It is a commonly stated rule of thumb that code is read more often than it is written. Even if writing code only for your own use, you will not remember everything about how it works when you read it back in 6 months time to make some amendment.
Your shortcut method names optimise your codebase for writing, because they make it quicker to type, and less error-prone.
However, they are actively harmful for reading, because they lead to less descriptive code, and require you to cross-reference the comment on the shortcut to check what it abbreviates.
Instead, you should aim to write the same code (thus retaining readability) but find tools to do so more easily and with fewer errors. A major helper in this case would be using a more powerful code editor or IDE, which will include auto-complete and code navigation facilities. You can also use standalone "code linting" / "static analysis" tools to pick up mistyped function names.
Performance shouldn't be an issue. But readability of your code suffers. You should use descriptive method names. If this function is called too many times it's a code smell and some refactoring may be needed.
I would not recommend creating shortcut methods. I am not sure why your methods do have such long names. Maybe your methods do more than one task?
for example:
$awesomeInstance->parseCheckAndSaveMyAwsomeObject();
in that case, you should write a dedicated method for each task.
Could you explain it in more detail?
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...
Is this a sign, that some design pattern is needed here?
/**
* #return string
*/
public function filter($string)
{
// underscored means private
$this->_prepareSomething($string);
$this->_prepareSomething2();
$this->_prepareSomething3();
$this->_prepareSomething4();
$this->_prepareSaveSomethingToFile();
return $this->getFiltered();
}
It's all about readability and the right level of abstraction. For me as the reader it's hard to see what data is exchanged between the _prepare* functions. And, let's pretend they are calculations of some sort, then saving some data to file is mixing business logic with persistance. Which looks like mixing of abstraction levels.
Also, the getFiltered() call is also confusing, as it looks like a public method is called with a similar naming scheme as the original function.
Patterns: See http://c2.com/ppr/wiki/WikiPagesAboutRefactoring/ComposedMethod.html for the composed method pattern explanation, and http://www.markhneedham.com/blog/2009/06/12/coding-single-level-of-abstraction-principle/ for the SLAP principle.
It looks like you're already implementing a Template Method pattern. If your class will have subclasses which may need to override certain steps in that process, then I'd say you've already designed your base class effectively.
I just want to tell you that I am newbie to OOP and it is quite hard to me, but here is my code:
class functions
{
function safe_query($string)
{
$string = mysql_escape_string(htmlspecialchars($string));
return $string;
}
}
class info
{
public $text;
function infos($value)
{
echo functions::safe_query($value);
}
}
Is there any way to make this sentence : echo functions::safe_query($value); prettier? I can use extends, than I could write echo $this->safe_query($value);, but is it a best way? Thank you.
edit: and maybe I even can to not use class functions and just make separate file of functions and include that?
Yes, just define your function outside of a class definition.
function safe_query($string){
return mysql_escape_string(htmlspecialchars($string));
}
Then call it like this
safe_query($string);
Using a functional class is perfectly fine, but it may not the best way to design your application.
For instance, you might have a generic 'string' or 'data' class with static methods like this (implementation missing, obviously):
class strfunc{
public static function truncate($string, $chars);
public static function find_prefix($array);
public static function strip_prefix($string);
public static function to_slug($string); #strtolower + preg_replace
etc.
}
The point of a class like this is to provide you with a collection of generic, algorithmic solutions that you will reuse in different parts of your application. Declaring methods like these as static obviates their functional nature, and means they aren't attached to any particular set of data.
On the other hand, some behaviors, like escaping data for a query, are more specific to a particular set of data. It would probably be more appropriate to write something like this, in that case:
class db_wrapper{
public function __construct($params); #connect to db
public function escape($string);
public function query($sql);
public function get_results();
}
In this case, you can see that all of the methods are related to a database object. You might later use this object as part of another object that needs to access the database.
The essence of OOP is to keep both the data and its relevant behavior (methods) in one place, called an object. Having behavior and data in the same place makes it easier to control data by making sure that the behavior attached to the data is the only behavior allowed to change it (this is called encapsulation).
Further, having the data and behavior in one place means that you can easily pass that object (data and behavior) around to different parts of your application, increasing code reuse. This takes the form of composition and inheritance.
If you're interested in a book, The Object-Oriented Thought Process makes for a decent read. Or you can check out the free Building Skills in Object-Oriented Design from SO's S.Lott. (Tip: PHP syntax is more similar to Java than Python.)
Functions outside a class litter the global namespace, and it's an open invitation to slide back to procedural programming. Since you're moving to the OOP mindset, functions::safe_query($value); is definitely prettier (and cleaner) than a function declared outside a class. refrain from using define() too. but having a functions class that's a mix of unrelated methods isn't the best approach either.
Is there any way to make this sentence
: echo functions::safe_query($value);
prettier?
Not really. IMO having a functions class serves no purpose, simply make it a global function (if it's not part of a more logical class, such as Database) so you can do safe_query($value); instead.
and maybe I even can to not use class
functions and just make separate file
of functions and include that?
Create files for logical blocks of code, not for what type of code it is. Don't create a file for "functions", create a file for "database related code".
Starting with OOP can be a real challenge. One of the things I did was looking at how things were done in the Zend Framework. Not only read the manual (http://www.framework.zend.com/manual/en/zend.filter.input.html, but also look at the source code. It will take some effort but it pays of.
Looking at the context of your question and the code example you posted, I would advice you to look at some basic patterns, including a simple form of MVC, and the principles they are based upon.
There are plenty of PHP frameworks out there as many of you know, and I am interested in your thoughts on this: Zend Framework has so-called action controllers that must contain at least one action method, a method whose name ends in "Action". For example:
public function indexAction() {}
The word "Action" is important, without it you can't access the method directly via the URI. However, in some other frameworks like Kohana you have public and private methods, where public methods are accessible and private are not. So my question is which do you think is a better approach? From a secure point of view I would vote Zend's approach, but I am interested in knowing what others think.
Based on preference, I am good with the zend framework's approach. It has proper controller encapsulation. Yes you must add the word action and create a view script(optional) for you to access it via URL. Yet you may still use the private,protected and public functions within the controller for additional logic.
It's preference really. Using some kind of naming convention is more versatile (and this is actually what Kohana 3 does now), since it allows for public methods that aren't actions, which can be useful.
Of course, the ideal solution is to use some kind of code metadata like .NET's attributes or Java's annotations, but unfortunately this feature doesn't exist in PHP.
This has less to do with security than it has to do with ZF's design. Like you said, the methods are not accessible when invoked through a URL, but that is solely due to how Zend Framework processes requests.
Quoting the reference guide:
The workflow of Zend_Controller is relatively simple. A request is received by Zend_Controller_Front, which in turn calls Zend_Controller_Router_Rewrite to determine which controller (and action in that controller) to dispatch.
Zend_Controller_Router_Rewrite decomposes the URI in order to set the controller and action names in the request. Zend_Controller_Front then enters a dispatch loop. It calls Zend_Controller_Dispatcher_Standard, passing it the request, to dispatch to the controller and action specified in the request (or use defaults).
The method names get formatted in Zend_Controller_Dispatcher_Abstract:
/**
* Formats a string into an action name. This is used to take a raw
* action name, such as one that would be stored inside a Zend_Controller_Request_Abstract
* object, and reformat into a proper method name that would be found
* inside a class extending Zend_Controller_Action.
*
* #param string $unformatted
* #return string
*/
public function formatActionName($unformatted)
{
$formatted = $this->_formatName($unformatted, true);
return strtolower(substr($formatted, 0, 1)) . substr($formatted, 1) . 'Action';
}
The Action suffix is hardcoded, so the Dispatcher will always look for an Action method, no matter what. So when you request /user/show/, the you'd call UserController::showAction() because of how the request is handled. It's not a security feature though or a replacement for Visibility. Make showAction() protected and you no longer have access to it through a URL either. And technically, you could very much call the non-action methods from a URI if you don't run them through the regular setup either. You could create your own Dispatcher and change how ZF formats action names easily.
What's nice about the Action Suffix, is it makes the action methods clearly distinguishable from other methods in the controller.
Zend has this because in PHP 4 you didn't have private/public, so they had to rely on naming conventions. It's more secure to both have public/private and a naming convention indeed.
i'd say it's down to personal preference. there are many variations here, for example codeigniter's version of this is that any method name beginning with _ is private and anything else is a controller method.
speaking personally, i'd say that anything using built-in language controls (eg public function vs private function) would be the most intuitive.
edit : as frank says, the MOST SECURE method would be one using as many features as possible (eg private as well as method name).