In an MVC Context, Where Do I Put A Class? - php

straight to the point :
I am using Kohana, and I am looking at another script written in plain PHP. In the script, I have a class ShoppingCart. If I am to convert the script to Kohana, where am I to put the class, its methods and its properties?
Is it in my existing default controller? Or should I put it in a separate controller? Or as noobie as it may sound, will I put it in the model?

That depends on the specifics of the class I suppose. To be honest I don't know anything about Kohana, but there's probably a place for "vendor files" somewhere. Maybe it's best to place it there and write wrapper functions for it in your controller. If the class already integrates well with Kohana you may instead choose to use it as a controller or model directly. Or you might want to take the time to rewrite it to make it work as a controller...
Only you can evaluate the best place for it, there's no hard and fast rule here.

Kohana has a folder for 3rd party libraries. The main one is under system/vendor, you can put it in you application/ as well.
Many PHP class loaders require details like your filename should be the same as the class name (at least that's what I read in the Kohana documentation) if you want the classes to be automatically loaded.

If you need to use 3rd party code in your app it's recommended that you create a folder in your app / module folder called 'vendor' and place all of that code there.
You can then include the files by calling:
include kohana::find_file('vendor', 'filename');
If needs be you can also create a wrapper for the external library, a good example of this is the email helper which uses the 3rd party Swift email library.
If you're porting your own class to kohana then you need to work out what the class will be doing and categorise it accordingly.
If the class will be fetching items from some kind of database then you should make it a model. Libraries are usually sets of code that you want reuse across controllers / models, such as authentication, calendar generation etc. Controllers are used for passing data from models to your views / libraries.
See the docs for more info

As per kohana convention, you should place custom classes in application/libraries folder. However for this, you need to know how to get the class to work after putting it there. If you can't figure that out, you can do anything like putting it in your controller or making another controller of it, etc.

Related

Joomla, is this a bad thing, injecting view, model and controller to container?

As the title says, I just want to ask if this is a bad thing or not if I inject all views, models, controllers and other classes like helpers into the container (IoC) for example like the following image.
Sample:
Note: In this case, I make my own base view, model and controller for my component so I don't use default Joomla instance like JModelLegacy::getInstance(); or JControllerLegacy::getInstance();.
Thanks.
This is what I did. I've tired of constant changes that breaks extensions and force to rewrite them without any actual benefit.
I have forced all MVC classes of Joomla and added my prefix to them. Everything works just fine.
I do not think you will have a problem to load everything at once. At least with the list you've shown. If you would have extension with hundreds of views and models, may be you could be hurt.
On the other hand why would you do that? Decouple your library off Joomla's and it will load everything automatically.

CodeIgniter: where should I put custom utils?

I'm using CodeIgniter and I have a few utils that I want each controller (that is, each controller file) to have access to.
The question is: where to put these?
I thought of helpers, but the CI documentation talks only about extending existing helpers, not making your own. I'm sure that doesn't mean I can't make my own helpers, but it does mean I don't know how they should be built (procedural? Methods of the global CI instance? etc)
I also considered hooks, but this is a poor fit I think as I'm not extending core functionality.
Or is there some other way I'm missing?
It's been a while since I've done this but I believe I used two approaches.
Creating a new, custom helper that goes into /application/helpers, following steps noted from this answer: CodeIgniter: Create new helper?
Creating a new library class into /application/libraries which I also activate in the autoload configuration found in /applications/config/autoload.php. This way it's always available to my controllers when I need it. CI has good documentation on this one (http://ellislab.com/codeigniter/user-guide/general/creating_libraries.html).
I did it simply by adding a file to the application/helpers folder (maybe I created that folder - I can't remember) and then loading them in the usual way.

Best location for Laravel App Utility class

I'm developing a app in laravel-4 PHP MVC framework
I'm wanting to develop some kind of utility class, for general coding tasks i carry out.
Such as: image uploading, image re-sizing etc... general application tasks
is it best practice to put all this in the base controller class? im thinking not, or defining a separate
UTILL::UtilityFunction();
// or
APP:UtilityFunction();
I'm not sure of the best way to structure this and keep it within best practice?
You're talking about a helper class, right? You better create classes to do whatever you need them to do, but they need to have a meaning on your app, they need to be specific, there's no problem creating a small class to do some image stuff and another one really small to upload files, but one utility class that does both is not good. Take a look at those articles: http://guru-php.com/blog/2008/08/128003/ and http://blogs.msdn.com/b/nickmalik/archive/2005/09/06/461404.aspx.
Using the same logic: you should add methods to your BaseControllers that are pertinent to all your controllers.
To create your utility classes, you can create a new directory (like app/library), create your classes inside it and add this path to app/start/global.php, in ClassLoader::addDirectories() list, Laravel 4 will autoload them automatically for you. Or you can add them to composer.json, using the autoload/classmap section and then run coposer dump-autoload to autoload them.

Organizing a PHP project

What It Is
Here is what I've done so far:
core/
controllers/ (contains the controllers used by the app)
models/ (contains the models used by the app)
views/ (contains the views used by the app)
base_controller.php (the controller every other extend)
base_model.php (the model every other extend)
vendors/
phprouter/ (a simple router class)
pimple/ (a simple DI container class)
configuration.php (contains all the app configuration)
index.php (includes the configuration, vendors, base model, base controller, sets the DI container up and route the request)
See the code here: http://pastebin.com/pxUpUvv6
Please note that the given code is just an example, therefore the controllers, models, views aren't in place yet. Also, it may be buggy—as untested—, but it doesn't matter right now.
Request Flow
The client requests index.php.
The configuration, vendors, base controller, base model are included.
The DI container and the dependencies are initialized, we can now inject them anywhere.
We map controllers to URL and the router does its job.
The controller is fetched (although this is not in the example code, as noted above).
We do some stuff.
The method then calls ::call_model(), which includes the corresponding model from core/models/, and then calls the same method we're using from the model class corresponding.
The model is fetched.
More stuff.
The model then calls ::call_view()', which includes the corresponding view from core/views/.
The view is fetched and render the page to the client.
FYI: Corresponding
Examples of controller, model, view which correspond:
Controller Controller_Products::list() at core/controllers/Controller_Products.php
Model Model_Products::list() as core/models/Model_Products.php
View at core/views/Model_Products_list.php
Issues Being Faced
Actually, I feel a bit uncomfortable with this structure. Dunno, it seems to be far from scalable, modulable...
Does only the basic folder structure—core{, /controllers, /models/, /views}, vendors at the root—looks good to you?
I feel like I should get __autoload() outside of index.php, which seems a little too big to me. If so, what about DI container?
Maybe if I get to needing more than two external library, it should be better not to have them included one by one, manually? But how?
Putting all the configuration in a file configuration.php at the root looks to me like old-fashioned PHP4. Thanks to the power of Pimple, I could embed this configuration directly into it but yet, where?
I think the way I handle ::call_model() (core/base_controller.php) and ::call_view() (core/base_model.php) is a bit awkward. Would you agree? What'd be a simplified way to redo the whole thing?
Considering all my issues, would it eventually be better for me to use a framework as Symfony?
If something isn't clear, feel free to ask.
Thanks.
Yes.
You can use autoload and DI container together. There is example, how autoload can be used with naming convention. I recommend to use spl_autoload.
With autoload you can remove all (or almost all) includes.
In index.php, I guess.
Yes, it's wrong way. First of all, try to not use static methods. Also, models should have methods with descriptive names, not just 'call me and I will do all what I can'. It's more complex problem - you need to understand how Controller and Model should do their cooperation. As variant, read some books. Controller should call methods of Model, to get data for some situation. Model it's not just place for code of controller. Different controllers can use different models. Models too can use another models.
Answer to this question can not be objective :)

What are some good ways to write PHP application with modules support?

I'm starting to write a application in php with one of my friends and was wondering, if you have any advice on how to implement module support into our application.
Or is there a way how to automatically load modules written in php by a php application? Or should i just rely on __autoload function?
And we don't need plugins that are installable via a web interface, we just need some clever way to associate web pages of our project to some classes (they will render the page) so index.php can call the right class and retrieve it's generated sub-page.
And we are not using any kind of framework, for now at least.
Re your comment: Autoloading in conjunction with strict file naming would be totally enough in this case IMO.
You could define a specific namespace (not in the new PHP 5.3 namespace way, just in the sense of a common prefix to names), e.g. Module_* for module class names.
You could then organize your modules in directories with class files that contain exactly one class definition, for example:
/modules/Mail/index.php // defines class Module_Mail
/modules/Database/index.php // defines class Module_Database
/modules/Image/index.php // defines class Module_Image
Your autoloader function would then, whenever a Module_* class is requested:
$Database = new Module_Database("localhost", .....);
include the correct file from the right directory.
That's the way e.g. the Zend Framework does it, and does so pretty well.
Consider choosing a more specific namespace than Module_ to assure interoperability with other scripts and applications if that is an option in the future.
Slightly related: In a PHP project, how do you organize and access your helper objects?
It sounds like you are looking for a way to organise the different tasks that each page needs to carry out. In this case, take a look at the MVC pattern. It provides a simple way to seperate your data access (models) and how you render/present information (views).
You can map pages to functions with ease. If you store the information in an array of mapped values, and then use a function to compare the requested URL with each of the URLs in the array. Such an array could look like this:
$urls = array(
'/' => 'index',
'/aboutus/' => 'aboutUs',
);
There are several articles that discuss how to implement it in PHP in a couple of hours. This article is a very simple guide. I am not a fan of their use of the registry pattern but reading through should provide you with enough information as to how you can implement it yourself.
Regarding autoloading, you can also use spl_autoload_register, to define several (more than one) autoload functions, so each module can set up it's own implementation of autoloading.
All you need here is an MVC architecture, with one Controller class associated with each "module".
If you are not against using a framework, go for Zend MVC
It allows you to have the following principle :
An URL like this : http://yoursite.com/my-module/edit
Will more or less automatically call the editAction method in the MyModuleController class.

Categories