I would to create a function/class that would be available in model, view and controller in cakephp. How do I go about it? Where do I create it?
/app/config/bootstrap.php is meant for such functions, but as the manual says:
Be careful to maintain the MVC software design pattern when you add things to the bootstrap file: it might be tempting to place formatting functions there in order to use them in your controllers.
Resist the urge. You’ll be glad you did later on down the line.
If you have more extensive functions or classes you can use the vendors directory, especially if you use third party libraries.
Related
I have a "simple framework" whose main instance is $app. Now, what is the best way to implement an autoloader (without using Composer). What I need is to have a class which handles all the autoloading (supporting the various namespaces). I have a few approaches/dilemmas.
At first I thought I should create a "static" class which handles everything. But then something came to my mind. If I use the autoloader before instantiating $app (which contains all the paths), I would need to define the paths outside of $app. And also if an error occours in autoloading a class, I wouldn't be able to handle the error properly (error handler is inside $app, and instantiated after).
Then I thought of dependency injection, making the autoloader an object inside the app. That would resolve the error handling problem, and wouldn't need me to hard code paths or making them globals. But I would have to load many classes (including $app) too before I can instantiate the autoloader.
But really I'm in a world of pain because of this issue, I don't really know where to start, are there some advices I should take into account ? Can you explain me which method should I use and why ?
Thanks.
As a result of the tips I got in this questions, I searched a bit more and found good resources from where to learn.
What's Autoloading ?
Autoloading is basically the process in which the program finds an unknown Class Name and attempts to load it without Class Name being defined. Without an autoloader, this behavior would result in a fatal error (for PHP at least). With an autoloader, things change, and the program will attempt loading Class Name, without knowing where to find it, but relying on functions or classes thought for this purpose, those functions/classes are called Autoloaders.
__autoload() vs spl_autoload_register()
In PHP we have two different ways to achieve autoloading (you might find useful to read it from PHP's site.). The first one is the old __autoload(), the newest is spl_autoload_register(). But what exactly is the difference ? Basically __autoload() is unique, having multiple Autoloaders would cause you many troubles and would get you in solving a problem which can be easily avoided by using the newest spl_autoload_* functions. spl_autoload_register() on the other side allow the program to have multiple Autoloaders by putting them in a stack, in this way the whole system becomes more flexible and much less complicated (having a single Autoloader for different purpose results in having a big unique function handling many requests, this way you'll have less code maintainability and reusability).
Warning: using spl_autoload_register() will overwrite __autoload(), so be careful.
Coding standards (in PHP): PSR-0 vs PSR-4
Let's start by saying that PSR-4 is newer and it was thought to be an improvement of PSR-0, but not compulsory you must use 4 instead of 0, as the standard (PSR-4) states:
It is fully interoperable, and can be used in addition to any other autoloading specification, including PSR-0.
So why should I use one instead of the other ?
Now this is up to you, but as a suggestion PSR-4 solves the "nesting" problem PSR-0, so you should be using the former. Let's suppose I have an application, and my application relies on external components, PSR-0 follows this syntax:
\vendor\(sub_namespaces\)class_name
Where sub_namespaces might be absent. But that translates to a fully qualified path on the hard drive:
path/to/project/vendor/sub/namespaces/class/name.php
Now let's suppose I want to include a library called YourLibrary in my application
\YourDeveloper\YourLibrary\YourFunction
This would translate to
/path/to/project/YourDeveloper/YourLibrary/YourFunction
And here's the problem, what if I want to put that library in a subfolder of mine:
/path/to/project/vendor/vendor_name
PSR-0 is absolute, you can't just modify the namespace to control this behaviour (it would be silly and require too much time) so it would translate to this:
/path/to/project/vendor/YourDeveloper/src/YourDeveloper/YourLibrary/YourFunction
Isn't that extremely nested and redundant ? Well, using PSR-4 you can avoid that and transform that into
/path/to/project/vendor/YourDeveloper/YourLibrary/YourFunction
Without altering the namespaces or the Autoloaders. That's basically how PSR-4 works. This explanation is quite short, but it gives you a glance of why PSR-4 was born and why you SHOULD use it. If you require a more adequate explanation, you can go and read the PSR-0/4 specifications or you can read this beautiful article on sitepoint.
Should I really be caring about standards ?
If you have been in the world of programming for enough time, you probably won't end up asking such question. But if you are, you are probably a new programmer, or you haven't been a programmer long enough, that's why you SHOULD read this answer.
In the IT world, and especially in programming, standards are almost everything. If we hadn't followed standards, we might not even have videos on our computers. If anyone follows their own standard, everything would look messy, and in this case, Autoloaders would become personal; so instead of having one SIMPLE Autoloader, you would end up having many Autoloaders, one for each standard, making your application much more difficult to maintain and to debug (because everyone can make erors).
If you writing a framework you should always look at existing ones, which properly allready solved your problem. Then you get inspired or just use that component. A great starting point is symfony, their components are seperated and tested. If you load it with composer or download it manually is your choice ;)
They also have a Classloader http://symfony.com/doc/2.0/components/class_loader.html which you could use as it. Or you just take a look what their approach is.
The Autoloader (or your classloader) should be the included at the beginning of your application and this should be the only class you include directly.
If you want to load your class dynamic your have to take a look how your store your classes, there are diffrent "standard" ways like PSR0 http://www.php-fig.org/psr/psr-0/. If you want your users to add their own classes, when they using your framework you should consider to support multiple standards.
I will use __autoload function in Codeigniter, but I'm not sure what is the best way.
I have read Phil Sturgeon's article and he uses at the bottom of config.php and
I asked to my friend, he uses in index.php
But I think they are not clean usage.
I want to use it in hook but I read this answer( last answer in the page ) How to add autoload-function to CodeIgniter?
and there is a negative vote on it.
Is to use in hook not good solution?
Codeigniter's autoload system is the easier way if you're using that framework: you just add the classname as index of an array and you're set.
Technically, it's not a "proper" autoloader, is a registry that checks if the class has already been instanciated in the static array of classes and, if not, adds it. In the way CI works it's efficient enough, and more important: is way easier for the user, compatible with any php version, and you don't need to code anything to implement it.
A proper autoloader using the __autoload() magic method, or better with spl_autoload_register() means you need to separate your loaded classes from what loads CI, and you need to implement it manually.
For future-ready applications check the PSR-0 standard which gives you indications on how to build a "standard" autoloader to be used to load classes in what's becoming the trend in PHP world: package management and distribution, similar to what other languages already do.
I'm still quite new to CodeIgniter and I was wondering, where should I place my PHP functions that has nothing to do with Controllers and Views, for example, a function that access a local file.
Thank you.
Do not use plugins as they are removed from CI 2.0 and you will have to convert them.
A group of functions that do not require data interaction should be placed in a helper.
Put loose functions into helpers. Group similar functions together into a helper and give it a meaningful file-name. Once the helper is loaded the functions can be used as though it were a require_once() or include.
If you have a class which has ostensibly "nothing to do" with Codeigniter, these can usually be converted into libraries with minimal or no effort.
Plugins are being taken out in CI 2.0, as Phil Sturgeon said, in favour of helpers and libraries. Which is a good thing, I think. Never had much need for 'plugins'.
You should place them in Controller, in controller you can put in even your own custom functions.
There are plugins and helpers directories where you can place files that include 'global' functions that are shared across your entire application.
That said, you should think before doing this, it may well make more sense to place the file in a model, if you are working with data stored on the file system.
I've asked this question on the zfforums as well, but I maybe I'll get a response here.
So the Zend Framework is a general purpose, flexible, loosly coupled, high quality framework. However, I find some of the MVC parts inconsistent and overly complex. Hopefully some of you can justify some of the zf design decisions and answer some questions:
General Questions/Comments
Why doesn't zend mvc follow the same naming conventions as other zend components? For example, mvc uses lower case, plural directory names and class names aren't prefixed with directory info so they can't be easily autoloaded.
I'd like the option to add a module root directory. That way, I wouldn't have to explicitly configure the dispatcher by adding controller/module directories. I'd be able to drop in a module and have it accessible immediately.
Why is there a distinction between view and action helpers? Currently, the helpers aren't designed to be shared throughout the code and there are inconsistent methods of loading and accessing the helpers. Other frameworks allow you to share the same helpers anywhere in your code. I don't see the need to specialize and violate DRY.
Zend View Questions
Why do views use "$this" to access resources? I don't see the need for the extra typing. Some other frameworks extract() an array of view variables and allow loading global functions or autoloading static helpers from within the view: myHelper::someMethod();
Why do view helpers only allow one function per class? That results in a lot of classes and associated maintenance. I'd prefer static classes with any number of methods as already mentioned.
I´m using the Zend Framework in a huge intranet site, since it´s early stages, 0.3 or 0.4 I think, and I followed the most of decisions regarding your questions. I´ll try to explain them a bit:
In most cases you don´t need to use modules. You can drop all your controllers in your application/default directory, name them IndexController or HelpController and you´re done, just access http://www.domain.com/ or http://www.domain.com/help.
If your project starts go grow you can add modules as you wish, prefixing them with the name of the module (directory name) Admin_IndexController or Forum_PostController, acessing them by http://www.domain.com/admin (you´re in admin module, index controller; not in default module/admin controller).
You can set your modules directory at applicatoin/modules, for example, and configure the FrontController to look at this directory for modules. Using addModuleDictory Whenever you create a new directory and put your view/controllers there, they´re auto-discovered by the dispatcher. Here is an example.
As I see they serve clearly distinct purposes. ViewHelpers are used to generate markup and render other actions directly in the view, abstracting menu creation, sidebar, etc. OTOH ActionHelpers interact with the dispatch process, allowing you to redirect to another action, as an example.
Views
In the beggining I too felt it a little awkward, but I got used to. I think the main reason is not to pollute the namespace, but I can be wrong with this. By the way I´m not very fond of the use of extract(), but it´s just my personal preference.
For the main reason that it´s not allowed to have more than one controller per file: autoloading. When you use $this->someViewHelper() the underlying engine looks for a class named *_SomeViewHelper_Helper in your plugin paths. Another reason is that static classes are very hard to unit test against. There´s even a proposal to rewrite the FrontController as an instance class, not a Singleton.
You´re right about the overly complex part that you say in your second paragraph and the developers and community knows about it. It just has to be this way to accomodate all requiriments and variations.
In the end I think that ZF is a very robust framework, giving us the freedom to do what we want.
I hope I could help you clearing your questions.
I don't know all the answers to these but they're interesting questions so I'll have a stab and hopefully someone can fill in the blanks.
General
Classes not in the default module are prefixed with the module name, e.g. Admin_IndexController and would reside in /admin/controllers. I think the reason for the separation, and inconsistent naming (vs. library classes) is that there would be little benefit having them in a nested folder structure. Controllers are part of your implementation so I think it makes sense, personally. Traversing the folders does get a little tiresome, however.
You could modify the dispatcher, or write a plugin to scan for directories and add them.
There is definitely overlap here - the URL helpers are a good example of this. Generally a view helper generates markup so I think there's a big enough distinction.
View
I don't know the exact reason but I'd guess it allows other helpers and view functionality to work together more easily. For example, if you've used the doctype helper to set the doctype, the form element helpers can generate XHTML or HTML as appropriate.
It definitely results in a lot of classes, but I'm not sure about maintenance. I've not run in to any problems. I can see the use in static classes, but remember that Zend_View won't stop you using them. If you have your static classes in your include path (and use Zend_Loader or similar), you can use them instead of or in addition to View Helpers.
I'm building my personal CMS and need your advice organizing core functions and classes.
I have folders:
/shared
/classes
DB.php
Session.php
Config.php
...
/libraries
Arrays.php
DateTime.php
Email.php
...
The files in 'classes' folder contains core classes (one class per file).
Now the question is about /libraries/ - they contain functions that may be used in any class, and sometimes they use some other function from another library, and sometimes they need to access some core class.
Should i just write them as functions, or make them static and wrap in some class?
Basically i need them everywhere, but keep them organized.
Should i just write them as functions,
or make them static and wrap in some
class? Basically i need them
everywhere, but keep them organized.
Have you looked into namespaces yet? Wrapping all of your functions into a namespace would probably be your best bet.
My suggestion is to first think through about the architectural goals of your CMS. Sure, it's going to be 100% yours, but that doesn't mean you wont suffer from not begin sure whats hooked where and how, what this does and how do I get that from here.
That's why I definitely wouldn't suggest you have libraries calling libraries. From my point of view, none of your classes should be dependent on anything else except for the first few core classes in your application flow since you'd like to distributed the work in some other single purposed self-contained classes. You should aim for singularity and atomicity with your core classes.
I don't know what your architectural pattern will be (I'll presume it's going to be MVC, HMVC or PAC), but I think it's best you first define a few core classes [/core] that will lay the foundations on initializing the application by instancing some libraries [/libraries] that are required for parsing the incoming requests request and doing some default tasks before initializing the requested controller [/controllers].
Libraries should have a single purpose. The session handling library should solely handle sessions, the routing library routing, etc. Initially you can create your base controller and base model and put it in [/core] and have controllers [/controllers] and models [/models] extend your base controller and model from [/core].
As always, the less coupled your components are the better. A good solution will be lightweight, small and extensive in it's purpose. It helps if you change any design ideas in the future that you can simply change the core classes and have a huge impact on the whole application without having to make any further changes in other places.