Chapter 12. Production Versions, Updates, and Big Decisions

The great day has come. Your development site is running well enough on your local development for you to transfer it to a production site hosted on a remote web server. It should be easy to do this. Copy over all the files, including the whole of the system folder, update the config settings, copy over and link to the database, and away you go. Sometimes, it really is that easy.

But when it isn't, it's always the night before you are giving an all-important presentation to a venture capitalist or a major prospect. So, in case this happens to you, this chapter covers:

  • What to look for in your config files

  • Some diagnostic tools to use if you get stuck

  • Some potential differences between servers that may trip you up

  • Some notes on security, now that you're out there in the big world

Next, this chapter covers upgrading, and looks at some of the ways in which CI has changed in the year it's been available. How stable is it? What decisions should you make if you are committing a critical site to it? And what should you do, once your site is up and running, if Rick Ellis brings out a newer version of CI?

Lastly, we briefly discuss making your own alterations to the core of CI. It's all there; it's open-source it's possible. Whether it's sensible or not is another matter.

Connections: Check the Config Files

Systems usually fail at the interfaces. That's what your config files are there for: to give you a place to put all those interfaces. If you haven't done so, you've missed one of CI's major strengths.

The major interface problems are likely to be:

URLs

CI works by finding files. Your user connects to index.php, and then a whole process of loading starts. At least, it should do. Make sure you have set the web address and server addresses correctly in your config files. The web address is your web root folder; you may have to ask your ISP for the server address, though usually it is clear from their own 'file manager' programme.

I've had particular issues trying to run sub-domains. Many hosts allow them, but map the domains to folders in ways you don't expect.

Databases

Locating and connecting to your database is often a major issue. Look at your config file and your config/database file. You need to make sure that you have the correct site and server addresses, and the correct database name, address, user name, and password. Be careful with prefixes sometimes these are added automatically. (Your site is called 'fred'. Your database, you think, is called 'mydata' and your user name is 'mylogin'. But the server thinks they are called 'fred_mydata', 'fred_mylogin', etc.)

Sometimes, it helps to create a new user on your database, even if you have one already, and set the log-in for this user's name and password. I have no idea why this works, but it does.

In the config file, you can set CI to accept different types of URI protocols, which determine how the server handles the URI string. The default is:

$config['uri_protocol'] = "auto";

but there are four other options that you can try if this doesn't work. If the correct option isn't set, you may find your site partly works, but (for example) forms don't call the target page.

Other config Files

The config/routes file sets the default path the application follows, if the user doesn't specify a controller/method through the URL (i.e. if they just log on to www.mysite.com). This should normally be set at the default:

$route['default_controller'] = 'index';

If you renamed the system folder, then remember that you also need to alter the index.php file in the site's root directory. The default setting is:

$system_folder = "system";

Look Out for PHP 4/5 and Operating System Differences

CI should be able to live with any version of PHP including and later than 4.3. However, this doesn't mean that any PHP code you write will also be compatible so if you wrote it on Xampplite using PHP 5, and are moving to an ISP with a PHP 4 server, look out for problems due to language differences.

PHP (of whatever version) can be set up in different ways. It's worth running phpinfo() on your local and remote sites, and checking for differences.

Case sensitivity is different between Microsoft and Linux servers. So if you've developed your site on a PC, and then uploaded it to a Linux-based server, expect the server to report that it can't find some of the models or libraries you want to load. If you've checked and they have been uploaded, then make sure that the capitalization is correct. Because class definitions and constructors in CI have to begin with a capital, it's easy to begin the file name with a capital too. If you load a model, say, inside a controller, and give it a capitalized name ($this->load->Mymodel), then Windows and Linux may have different views about calls to $this->mymodel.

As an extreme example of server differences, I once began to write a controller, decided to make it a model instead, and so saved it in the model folder without realizing that I had left the first few lines as:

class Myclass extends Controller {
function Myclass()
{
parent::Controller();

instead of changing them to:

class Myclass extends Model {
function Myclass()
{
parent::Model();

Running locally on Xampplite, this did not throw an exception. Transferred to a remote Linux server, it immediately failed (and you can imagine how long it took to track down…).

Some PHP functions also appear to behave differently on different operating systems: for instance, include_once() is case insensitive on Windows but not on other systems. That's not specifically a CI issue, though.

Also, your database may be a different version many ISPs are very traditional, running MySQL 3.23 for instance! This seems to cause some incompatibilities, which means that uploading a database by a SQL query is less easy than it should be. (For instance, it may not accept comments on db tables.)

Linux has a different system of file permissions to Windows. Make sure that you have the correct permissions on your files and folders. Certain CI file permissions must be set correctly before the system can work.

Diagnostic Tools

The first line of the index.php file is:

error_reporting(E_ALL);

which displays any PHP errors on your screen, like this:

Diagnostic Tools

Obviously, error reports like this look bad, and may give hackers too much information, so for the production version you alter this to:

error_reporting(0);

But then, any problems may simply result in a blank screen, with no helpful diagnostic information. You may have to turn error reporting back on, until you have got the site running. One compromise is to set it to an intermediate level, such as:

error_reporting(E_ERROR);

This will prevent 'warnings' but will still give you information about serious problems. 'Warnings' are usually conditions that don't stop the programme from executing, but may point to other underlying issues that you hadn't considered.

The CI Profiler class see Chapter 8 is also very useful: it shows you what queries you are doing, and what is in the POST array.

Various other tools I have found useful when things don't work:

  1. Set CI to print a log file. (Done from the config file see Chapter 8 you need to set:

    $config['log_threshold'] = 4;
    

    shows all messages, including just notices and warnings; sometimes these are pointers to an underlying problem. Then look at the log (printed in /system/logs, fled by date.) This will tell you which parts of the CI system have been called, so you can at least see where the process stopped. (Set the value back to 0 to prevent further logging. Remember to do this, and to removethe log fles when you've fnished: it's amazing how much space they take up.)

  2. If you can access them, print out the PHP server and session variables:

    print_r($_SERVER)
    

    and:

    print_r($_SESSION)
    

    and use them to check that the document_root and script_filename values are what you expect. If not, you may need to adjust your config file values for base_url and server You can also see if there is an [HTTP_COOKIE]value set, which will show you if your session class is enabled and working.

  3. Check what CI has loaded into its superobject by using PHP's methods:

    get_declared_classes();
    

    and:

    get_class_methods();
    
  4. CI's own show_error() function is only a means of formatting error reports that you generate. So including the following line in your code, say at some branch that should not be reached:

    show_error('test of error function'),
    

    would result in your screen showing:

    Diagnostic Tools

    I don't find that very useful. What I want is a system that will give me full, helpful error reports, when and where I want them, but won't show them when I don't want them to appear. I wrote my own function, which reads:

    function reportme($file, $line, $message)
    {
    $obj =& get_instance();
    if(isset($_POST))
    {$bert = print_r($_POST, TRUE);}
    else {$bert = 'no post array';}
    if(isset($_SESSION))
    {$sid = print_r($_SESSION, TRUE);}
    else{$sid = 'no session array';}
    $time = Gmdate("H:i j-M-Y");
    /*full report*/
    $errorstring = "$time - $file - $line: $message: POST array: $bert SESSION array: $sid
    ";
    /*short report*/
    $shortstring = "$file - $line: $message";
    /*set $setting to 'test' if you want to write to the screen*/
    $setting = 'test';
    if($setting == 'test')
    {echo $errorstring;}
    /*set $action to 'log' if you want to log errors*/
    $action = 'log';
    if($action == 'log')
    {
    $filename = $obj->config->item('errorfile'),
    $fp = fopen("$filename", "a+")or die("cant open file");
    fwrite($fp, $errorstring);
    fclose($fp);
    }
    }
    

    This lives in a library called errors. I have to remember to load the library, and then, whenever I have a section of code that I'm not confident about, I include the function:

    $this->errors->reportme(__FILE__,__LINE__,'if the code has reached here it is because......'),
    

I can then set the reportme() function to give me a report on the screen, or in my log file.

There are several advantages to a simple method like this. Firstly, I can alter the reportme() function easily, to make it write errors to a file, or to do nothing at all: so I can make all my reports disappear from the screen at once, or come back again, by changing one line of code.

Secondly, let's say I am expecting a variable to have a particular value. (An ID number to be an integer, say.) I make the message as complete and helpful as possible. I try to say what I expected to find (an integer), as well as including the value I actually got. The function call also uses PHP's __FILE__ and __LINE__ 'magic constants' to tell me exactly where it happened.

So, if this particular piece of code becomes a problem when I transfer it to another server, possibly some time after I wrote it, I can immediately find the code, and the text helps me to remember why it is a problem. Six months after you write code, you can't just pick it up straight away, especially if it is late at night and a client is on the phone asking for an explanation! The more helpful the error text, the easier it is to respond sensibly.

Thirdly, if the integrity of the site was really critical, I could set the function to email me with error reports. That might result in a very full mailbox during the development phase, but once the site is stable and in use, it might be very useful to have an immediate warning if the site is experiencing problems. You will know about them before your users tell you.

Coping with Change in New CI Versions

Between 28 February 2006 and 30 October 2006, CI went from its first beta to version 1.5. That's a pretty impressive rate of development.

During that time Rick Ellis made several fairly radical changes, particularly to the structure of the site. For the most part, he has been careful to make them backwardly compatible but not all of them are. If you are new to CI and have downloaded the latest version, you can skip this section. But if you wrote programmes using earlier versions, you may need to check these changes. You may also need to check if you are using CI libraries or plug-ins written by other people.

Rick has grappled with two main problems:

How to Load Models, and What to Call Them

At first, there were no models, just folders for scripts and libraries. There was no provision to initialize them automatically as part of the CI 'super-object'. As a result, you had an MVC system without 'model' files, which seems confusing.

As well as this, there are two libraries folders: /system/application/libraries holds any files you write for yourself, while /system/libraries holds the system's own operating files. This may have confused a few people: the two are quite different! You ought to be adding to or altering the former; you probably don't need to alter the latter. (And if you do, you run serious risks of incompatibility if you upgrade to a later CI version: see below.)

With version 1.3 came a new 'model' class. The User Guide defines models as, "PHP classes that are designed to work with information in your database". When first introduced, CI models connected automatically to the database. However, since Version 1.3.3, you must specifically load the database from inside the model or the controller that calls it.

Or, when you call the model from the controller, you can do so in this format:

$this->load->model('Mymodel', '', TRUE);

and then the 'TRUE' loads the model with the default database connection made, as defined in your config file. (The second parameter, left blank here, is an optional alias for the model.)

CI will probably still work if you put the functionality of a 'model' (in the MVC sense) into a 'library' or a (deprecated) 'script', as you had to in the early days when there were no 'models' folders: but you'll have to access the CI resources differently see the next section!

How to Initialize Your Own 'library' Classes

Originally, you couldn't make your own classes part of the CI 'super-object'. This was a problem, because it meant that your library code couldn't, for instance, access the database through Active Record, or use other CI libraries, and that became pretty limiting.

Version 1.2 added the get_instance() function that allows you to access the 'super-object'. (See Chapter 7.) You could include it in your 'library' or 'script' and then use the CI resources. (Unless your new file was a functional script rather than an OO class, of course. However, script files are probably best used for simple low-level functions.)

Version 1.4 introduced a new system. You had to create two files for each 'library' class. The first was the class itself, say Newclass.php, stored in the application/libraries folder, and the second, stored in an application/init folder, had to be called init_newclass.php and contained a few standard lines of code that initialized it as part of the 'super-object'. However, you still had to use the get_instance() function to access CI resources.

In version 1.5, the init folder has been deprecated, and initialization happens automatically. You now only need the one file for each 'library' class.

The old scripts folder has also been deprecated. 'Deprecate' in this context, usually means that the thing concerned is till recognized and should still work, but that the developer offers no guarantee that it will do so in all future versions. In other words, don't panic if you still have scripts in a system/application/scripts folder but don't write any more.

If you are planning to use libraries or plug-ins written by the CI community, please check first that they are up to date with the latest CI version. There are quite a few around still that were written for 1.4.1 and have separate 'init' files. Updating them isn't difficult, but it does take some care to get it right.

So Should I Update If a New CI Version Comes Out?

New versions of CI come out from time to time. They come with comprehensive instructions for updating. Usually, this involves copying a new set of files to your system folder. Sometimes, you need to change config files, or your index.php file, as well, but none of these are major changes and none of them are rocket science. Because the folder structure keeps your application files in their own place, it's usually easy to update the system without touching the applications.

But, say you've written your killer app in version 1.5. It's uploaded to your production system and working fine. Then, Rick Ellis brings out CI version 1.6 (or 2.8 or whatever…). It has interesting new features, and some bug fixes. Do you upgrade to it?

I would say, 'Yes', if it's a minor upgrade, say between 1.5.2 and 1.5.3. But if it's a major version change, and your existing system is working, leave well alone. You can tell the difference partly from the numbering, but also from the 'change log' published with each upgrade when it comes out. The sort of changes that have been made in CI over the last year fall into three categories:

Bug fixes: There are surprisingly few of these CI is excellent code, and most of the base classes have been well tested by hundreds if not thousands of users.

New features:. These appear regularly, but if you managed to build your application without them, will they really be helpful now?

Subtle changes: As I've described, CI has gone through a process of internal evolution, and it may well continue to do so. As you can see from the following table, some of these might be backwardly compatible, or they might require fairly major re-writes of your code.

Some changes between versions of CI:

Version

Change Log

1.2

Added a global function named get_instance() allowing the main CodeIgniter object to be accessible throughout your own classes.

1.3

Added support for Models.

1.3

Added the ability to pass your own initialization parameters to your custom core libraries when using $this->load->library().

1.3

Added better class and function name-spacing to avoid collisions with user developed classes. All CodeIgniter classes are now prefixed with CI_ and all controller methods are prefixed with _ci to avoid controller collisions.

1.3.3

Models do not connect automatically to the database as of this version.

1.4

Added the ability to replace core system classes with your own classes.

1.4

Updated the Models loader function to allow multiple loads of the same model.

1.4.1

Updated plugins, helpers, and language classes to allow your application folder to contain its own plugins, helpers, and language folders. Previously, they were always treated as global for your entire installation. If your application folder contains any of these resources they will be used instead the global ones.

Version

Change Log

1.4.1

Deprecated the application/scripts folder. It will continue to work for legacy users, but it is recommended that you create your own libraries or models instead. It was originally added before CI had user libraries or models, but it's not needed anymore.

1.5

Added the ability to extend libraries and extend core classes, in addition to being able to replace them.

1.5

Deprecated init folder. Initialization happens automatically now.

Don't misunderstand me. All of these are sensible changes and all of them are improvements. If you are starting a new project, start with the latest CI version. But if you wrote code using version 1.3, say, you will find that your scripts folder is deprecated and your models don't automatically connect to the database any more. Personally, I would leave that code running on version 1.3 of CI, rather than try to upgrade it. Life's too short.

How to Add On to CI's Basic Classes

Normal users are unlikely to need to alter the base CI classes. It's a pretty good framework, it does a lot of things, and after all, the point of a framework is to make thing easy, right? However, if you must ….

CI is open source, and you can see all the code as soon as you download it. This includes the basic libraries that make CI work (stored in system/libraries) as well as the ones you wrote in system/application/libraries.) So it has always been possible to change CI any way you like.

Changing system library files has two problems, however:

  • There's no guarantee that your new code will be compatible with the rest of CI, or with updated versions. This may lead to subtle or strange errors that won't be easy to track down.

  • If you later update your CI version, the system folder is likely to be changed. The library file you altered may well be over-written and updated, so you'd have to go through your changes and transfer them to the updated version.

However, since version 1.5, there are now two sensible 'work-arounds' for tinkering with the CI library classes (except for the underlying 'database' and 'controller' classes, which you touch at your peril.)

  • Firstly, you can create a file with the same name as any of the system base classes in your /system/application folder. The system then uses this one, in preference to the standard one in the /system folder. This requires exact naming conventions see the online User Guide. It also requires you to copy all the functionality in the existing class as well as your own additions or changes.

  • Secondly, and more conveniently, you can create a new class that extends the system class. (So it's perhaps best referred to as a 'sub-class'.) Again, there are naming conventions see the online User Guide. Extending the underlying system class means that your new sub-class inherits all the resources of the underlying CI class, but adds a few extra methods of your own. This should mean that, if you update your CI version, the underlying CI class will be replaced, but your new sub-class (which you should put in the system/application folder) will be left untouched.

However, neither of these methods will guarantee that your code is (or remains) compatible with the rest of CI.

Looking through the CI online forums, there are various suggestions for extending the Validation, Unit Testing, and Session classes. Unit Testing, for example, only has two functions and a limited number of comparisons. Perhaps you want a function to show up errors in red, so they stand out when the test results are returned?

If you wanted to make extensive use of some other testing function, it would be simpler to add it in via a sub-class, extending Unit Testing, than to write it out in the controller each time you called Unit Testing.

If you wanted to do this, you'd start your new sub-class this way:

class MY_Unit_test extends CI_Unit-test { function My_Unit_test() { parent::CI_Unit_test(); }
function newfunction()
{
//new code here!
} }

Notice three things here:

  • The name of the underlying unit testing class is CI_Unit_test, even though the filename of the class code is system/libraries.unit_test.

  • If you need to use a constructor in your sub-class, make sure you extend the parent constructor first, as here.

  • Your new sub-class name should be prefixed with MY_, and saved as application/libraries/MY_unit_test.php. (Unlike the main classes, where the CI_ prefix is part of the class name but not of the filename, here the MY_ prefix is part of both.)

Once you've created your sub-class, you load it like this:

$this->load->library('unit_test'),

In other words, exactly the same as before you wrote the sub-class; and you call a function in the same way too, except that this time you can call not only the existing unit test functions, but also any new ones you've written yourself:

$this->unit_test->newfunction();

When you next update your CI installation, the unit test library in the system folder will be overwritten, but the one in the application folder won't, so your code will still be there. Of course, you'll need to check that the updated system library is still compatible with your own code.

Summary

In this chapter, we've seen some of things that can go wrong when you try to transfer your system from a local server to a remote one. This may involve:

  • A different version of PHP or MySQL

  • A different operating system

In particular, we've looked at case sensitivity, PHP differences, and MySQL issues. We've also looked at diagnostic tools.

Then we looked at the CI's updates. These have all been major improvements, but my advice is, if you have a system working on the current CI version and a new one comes out, think carefully before you upgrade.

Lastly, we looked at the pros and cons of adding to CI's basic classes. Most users won't need to do this, but if you want to, I strongly suggest that the best way to do it is to sub-class an existing library class.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.145.114