I am just getting started with CodeIgniter, and I am trying to hash out my regular modules/functions to get them working properly within the MVC framework. I have a few specific questions for anyone who has a strong CodeIgniter background:
SESSIONS
The CodeIgniter session stores session data on the client side in a cookie, which just isn't going to work for me. I know there are a few replacements for it, or I could build my own library/helper; but I just don't see any benefit over just using $_SESSION.
If I just use $_SESSION, will I have any problems with the rest of the framework? Does any other part of the framework depend on using the CodeIgniter session?
I feel a bit weird about stepping outside the framework for something so basic, but I am pretty comfortable with plain PHP. I am basically just looking to use CodeIgniter for MVC, and to enforce a more modular aspect for my projects.
CODE FLOW & CONFIG
I have a few config items that need to be done before almost anything else.
For example, say I have a constant APP_LIVE, which is set true/false based on the name of the current server. This has to happen really early as paths, error reporting, the CodeIgniter system, and application folders, etc. will be set based on it.
The problem is that the system_folder, and application_folder (which will be set based on which server the code is running on) are set first thing in the index.php file, before any of the configs have loaded.
Also, I have a functions that check for things in the URL, and may redirect before the page ever loads. For example, some pages need to enfore the presence of www. in the URL (for SEO), track affiliates, visitor sources, marketing flags, etc.
Where is the best place to put things like this that have to happen really early? I know there is a config file, an autoload file, a constants file, etc., but those are too late for some items. Is it a bad practice to simply put these things into the top of the main index.php file, or to make an include there to a global config file? Again, I feel like I am stepping outside the framework, and wonder if I'm just doing that because I don't have a solid understanding of it yet?
LAYOUT / HEADER FOOTER
Like most people, I have a top header, navigation, footer, etc. I am used to just having them in files, which are included into my page template. I believe I can do that the same way by just making them views and including them into my main page view. Is that the best way to go? Some of them need a bit of data; like what page they are on for the navigation, etc. What's the best way to handle navigation, shared header/footer, etc.?
The newly released CI 1.7 handles sessions in the database (if you're using one).
However, CI is designed to be loosely coupled, so you shouldn't notice any major issues if you decide to use $_SESSION instead.
For your header / footer / navigation, you could create (for example) headerview.php, footerview.php, and contentview.php, and pass data to your views by doing something like this in the controller:
$data['title'] = 'about us';
$data['content'] = 'hello world!';
$this->load->view('headerview', $data);
$this->load->view('contentview', $data);
$this->load->view('footerview');
Basically, you can treat these views exactly like includes, but with the added benefit that you can change the variables within. I would steer clear of calling other views from within views, but that might just be me.
I've made additions to index.php myself once or twice, to set initial values and such, and have never had a problem with it.
Congratulations on your choice of framework; I'm sure you won't be disappointed. ;)
You can either have multiple load->view lines in every controller but I personally find it coupled. I strongly suggest that you take a look at hooks in CodeIgniter where you can define functions that would be automatically run after each controller/method (a fine example of AOP).
Actually the $_SESSION array seems to get unset so you can't use the native PHP sessions (at least on 1.7). However in CodeIgniter wiki there's a session class that uses the native php sessions - you can use it the same way as the other, but it stores only session_id in the cookie. Here it is:
http://codeigniter.com/wiki/Native_session/
#lacho I created my own auth library on $_SESSION. and it works fine on 1.7.
I believe $_SESSION is much more secure since CI 'sessions' are cookies that are stored on the client side which are classified as 'user-passed-information' that can't be trusted.
You can try with native using your own session class
http://www.moreofless.co.uk/using-native-php-sessions-with-codeigniter/
Related
I'm in the middle of moving my site into the CodeIgniter framework. I've never used a MVC framework before so this is a big step.
In my old site, each page would have include("session_handler.php"); at the top of each page. This script would check session variables, authenticate sessions and store stuff in the database.
Is there a way I can have this script automatically include in every page? Can I specify it in the config? Does CI maybe have an internal way of dealing with sessions that is superior to my method?
Code Igniter has a Session class you can use.
It also has an autoload functionality.
Those two things should cover your requirements I think...
If you need additional validation to the session, you can either extend the core session class (which may be asking too much if you're only starting on the framework) or you can create your own library and auto-load it right after the session one to run some additional code..
I see many MVC implementations for websites have a single-entry point such as an index.php file and then parses the URL to determine which controller to run. This seems rather odd to me because it involves having to rewrite the URL using Apache rewrites and with enough pages that single file will become bloated.
Why not instead just to have the individual pages be the controllers? What I mean is if you have a page on your site that lists all the registered members then the members.php page users navigate to will be the controller for the members. This php file will query the members model for the list of members from the database and pass it in to the members view.
I might be missing something because I have only recently discovered MVC but this one issue has been bugging me. Wouldn't this kind of design be preferable because instead of having one bloated entry-file that all pages unintuitively call the models and views for a specific page are contained, encapsulated, and called from its respective page?
From my experience, having a single-entry point has a couple of notorious advantages:
It eases centralized tasks such as resource loading (connecting to the db or to a memcache server, logging execution times, session handling, etc). If you want to add or remove a centralized task, you just have to change a singe file, which is the index.php.
Parsing the URL in PHP makes the "virtual URL" decoupled from the physical file layout on your webserver. That means that you can easily change your URL system (for example, for SEO purposes, or for site internationalization) without having to actually change the location of your scripts in the server.
However, sometimes having a singe-entry point can be a waste of server resouces. That applies obviously to static content, but also when you have a set of requests that have a very specific purpose and just need a very little set of your resorces (maybe they don't need DB access for instance). Then you should consider having more than one entry point. I have done that for the site I am working on. It has an entry point for all the "standard" dynamic contents and another one for the calls to the public API, which need much less resources and have a completely different URL system.
And a final note: if the site is well-implemented, your index.php doesn't have to become necessarily bloated :)
it is all about being DRY, if you have many php files handling requests you will have duplicated code. That just makes for a maintenance nightmare.
Have a look at the 'main' index page for CakePHP, https://github.com/cakephp/cakephp/blob/master/app/webroot/index.php
no matter how big the app gets, i have never needed to modify that. so how can it get bloated?
When deeplinking directly into the controllers when using an MVC framework it eliminates the possibility of implementing controller plugins or filters, depending on the framework you are using. Having a single point of entry standardizes the bootstrapping of the application and modules and executing previously mentioned plugins before a controller is accessed.
Also Zend Framework uses its own URL rewriting in the form of Routing. In the applications that use Zend Framework I work on have an .htaccess file of maybe 6 lines of rewriterules and conditions.
A single entry point certainly has its advantages, but you can get pretty much the same benefit from a central required file at the top of every single page that handles database connections, sessions, etc. It's not bloated, it conforms to DRY principles (except for that one require line), it seperates logic and presentation and if you change file locations, a simple search and replace will fix it.
I've used both and I can't say one is drastically better or worse for my purposes.
Software engineers are influencing the single point of entry paradigm. "Why not instead just to have the individual pages be the controllers?"
Individual pages are already Controllers, in a sense.
In PHP, there is going to be some boilerplate code that loads for every HTTP request: autoloader require statement (PSR-4), error handler code, sessions, and if you are wise, wrapping the core of your code in a try/catch with Throwable as the top exception to catch. By centralizing code, you only need to make changes in one place!
True, the centralized PHP will use at least one require statement (to load the autoloader code), but even if you have many require statements they will all be in one file, the index.php (not spread out over a galaxy of files on under the document root).
If you are writing code with security in mind, again, you may have certain encoding checks/sanitizing/validating that happens with every request. Using values in $_SERVER or filter_input_array()? Then you might as well centralize that.
The bottom line is this. The more you do on every page, the more you have a good reason to centralize that code.
Note, that this way of thinking leads one down the path of looking at your website as a web application. From the web application perspective, a single point of entry is justifiable because a problem solved once should only need to be modified in one place.
I am considering to use a php framework (never used one before), I know I have to abandon the way I am used to work (I can deal with this), among many concerns a first thing that comes in my mind is this:
I have two techniques I like to use (have used them for years)..
I always use index.php?somePage.php as href so never loads another page other that index.php, then index.php includes the somePage.php
I always used to store all texts, any text, titles, button names, link names, stories, articles, anything, in a single (or more) files or in GLOBALS array (depending on size).
I want to ask is this aproach wrong, is there any better way?
Second, from what I have read freamworks have some rules, does my approach create some conflict? I am thinking of KISS_MVC framework cause it declares to be easy for framework beginers.
I have no experience with frameworks and I am concerned, about all this, I can't wait for the day I will feel like home with using a framework.
Thank you all in advance!
That pattern is known as front controller - it gets all requests and routes them internally (not based on file loaded). That pattern is fine, it should look like /index.php/whatever to which you can then patch over with .htaccess to make /whatever (Examine $_SERVER['REQUEST_URI']).
Database is a good place to store large amounts of text. Files you create rarely are - they offer none of the advantages of using a database. $GLOBALS rarely is a good place to store data. You generally should keep as little as possible available globally. You can make a registry class to store global stuff if you need.
The best way to know what does and doesn't work with a framework is to try and get familiar with a popular one such as Zend, Kohana, Yii, etc.
I am taking over an existing PHP project. I noticed that the previous developer uses a one index.php page for the entire site, currently 10+ pages. This is the second project that I have seen done like this. I don't see the advantage with this approach. In fact it seems like it over complicates everything because now you can't just add a new page to the site and link to it. You also have to make sure you update the main index page with a if clause to check for that page type and then load the page. It seems if they are just trying to reuse a template it would be easier to just use includes for the header and footer and then create each new page with those files referenced.
Can someone explain why this approach would be used? Is this some form of an MVC pattern that I am not familiar with? PHP is a second language so I am not as familiar with best practices.
I have tried doing some searches in Google for "single index page with php" and things like that but I can not find any good articles explaining why this approach is being used. I really want to kick this old stuff to the curb and not continue down that path but I want to have some sound reasoning before making the suggestion.
A front controller (index.php) ensures that everything that is common to the whole site (e.g. authentication) is always correctly handled, regardless of which page you request. If you have 50 different PHP files scattered all over the place, it's difficult to manage that. And what if you decide to change the order in which the common library files get loaded? If you have just one file, you can change it in one place. If you have 50 different entry points, you need to change all of them.
Someone might say that loading all the common stuff all the time is a waste of resources and you should only load the files that are needed for this particular page. True. But today's PHP frameworks make heavy use of OOP and autoloading, so this "waste" doesn't exist anymore.
A front controller also makes it very easy for you to have pretty URLs in your site, because you are absolutely free to use whatever URL you feel like and send it to whatever controller/method you need. Otherwise you're stuck with every URL ending in .php followed by an ugly list of query strings, and the only way to avoid this is to use even uglier rewrite rules in your .htaccess file. Even WordPress, which has dozens of different entry points (especially in the admin section), forces most common requests to go through index.php so that you can have a flexible permalink format.
Almost all web frameworks in other languages use single points of entry -- or more accurately, a single script is called to bootstrap a process which then communicates with the web server. Django works like that. CherryPy works like that. It's very natural to do it this way in Python. The only widely used language that allows web applications to be written any other way (except when used as an old-style CGI script) is PHP. In PHP, you can give any file a .php extension and it'll be executed by the web server. This is very powerful, and it makes PHP easy to learn. But once you go past a certain level of complexity, the single-point-of-entry approach begins to look a lot more attractive.
Having a single index.php file in the public directory can also protect against in the case of the php interpreter going down. A lot of frameworks use the index.php file to include the bootstrap file outside of the doc root. If this happens, the user will be able to see your sourcecode of this single file instead of the entire codebase.
Well, if the only thing that changes is the URL, It doesn't seem like it's done for any reason besides aesthetic purposes...
As for me - single entry point can help you to have better control of your application: it helps to handle errors easily, route requests, debug application.
A single "index.php" is an easy way to make sure all requests to your application flow through the same gate. This way when you add a second page you don't have to make sure bootstrapping, authentication, authorization, logging, etc are all configured--you get it for free by merit of the framework.
In modern web frameworks this could be using a front controller but it is impossible to tell since a lot of PHP code/developers suffer from NIH syndrome.
Typically such approaches are used when the contents of the pages are determined by database contents. Thus all the work would get done in a single file. This is seen often in CMS systems.
I'm building an IMDB.com like website using PHP/jQuery and a MVC approach (no OOP).
I have an index.php base controller to 'rule them all' :), a controllers folder with all the controllers, a models folder and a view folder.
In some pages of the website I have tabbed navigation, when the visitor clicks on one of those tabs to get more information, jQuery gets that data using the $.post or $.get method and shows it on the tab container, obviously without refreshing the page.
The problem is that those pages loaded by ajax are also generated using controllers, models, and views, and the things are getting a bit complicated for someone like me ( = 'no experience'). To dynamically get the data I some times need to include a model twice, include an include in an include in an include, send information multiple times, connect with the database again, and all sort of things like that and I'm sure there is a better and prettier way to do this.
I'm searching for the best approach and common methods for this. I have no experience working with a big project like this. This is a personal project so I have full control and every answer is welcome.
Thanks!!!
You can check the X-Requested-With header that most js frameworks send to see if the request is coming via ajax. Then you can only output certain data and not the "entire page".
Not sure why you need multiple includes like you say, maybe you need to rework your logic.
Post some code and we can be of better help.
"To dynamically get the data I some times need to include a model twice, include an include in an include in an include, send information multiple times, connect with the database again, and all sort of things like that and I'm sure there is a better and prettier way to do this."
I think you need a better 'design' for you MVC application. Multiple includes - i am guessing in the different layers of the MVC framework might be indicators that your design needs more attention.
I'll try and be short:
Other frameworks i.e. handle requests via XMLHTTPRequest by AMONG others, disabling or enabling the VIEW or LAYOUT explicitly - check Zend Framework - (e.g. you need to send a JSON encoded string as a response). These requests are handled just as any other request.
I would suggest you have a look at other popular frameworks. Check the application design and layout, and pay attention on the Routing and Dispatching of Actions. I suggest you follow this path since as you say you lack experience.
good luck with your project.