官术网_书友最值得收藏!

MVC: Model-View-Controller

What's MVC all about? For sure at this time you are very curious about this. In short, MVC is an architectural pattern, a way of structuring our application. When you were reading the previous chapters you had a glance at it; remember when we explored the file structure? At that time we saw that CodeIgniter was divided into these folders (among others):

system

application

models

views

controllers

As you can see there is a folder for each of the words (MVC); let's see what we can put into them:

  • Models: The models represent our application data, be it in databases, in XML files or anywhere else. Also, interaction with databases is carried here. For example, models will allow us to fetch, modify, insert, and remove data from our database. All actions that require our application to talk to our database must be put in a model.
  • Views: Files placed here are responsible for showing our data to the visitors to our site, or users of our application. No programming logic, no insert or update queries must be run here, though data access may occur in these files. They are here only to show the results of the other two. So we fetch the data in the model, and show it in the view. Now, what if we need to process the data, for example, putting it into an array? Then we do it in the controller; let's see how.
  • Controllers: These act as a nexus between models and views, and programming logic occurs here.
MVC: Model-View-Controller

Take a look at this little diagram, in the left column we can see a "classical" way of doing things (a little outdated right now). We have a PHP file with SQL queries and HTML code in the same file and embedded into the HTML PHP logic.

It may seem, at first glance, that this way it is easier and faster to program. But in this case the code gets messed faster and becomes cluttered with SQL queries, HTML, and PHP logic. Look at the right-side column—we have SQL queries in the Model, HTML and other graphic elements in the View, and PHP logic in the Controller. Doesn't that seem organized? The Controller calls and fetches data from the Model. It then loads the data and passes it to the Views, and sends the results to the user.

Once we start working with this pattern we will feel how easy it is; it will keep our projects organized. If we need to come back to our project months after finishing it we will appreciate having made it in a structured fashion. No more of—Oh my God where did I put that query, where is that include file?—they will be in the model and the controller respectively.

But, what happens if we want to put our queries in the controller? Well, CodeIgniter allows us to do so (though it is not recommended; if you can avoid, it is better to do so). As we saw in the previous chapters CI is here to help us. Other frameworks force you to keep a particular structure, but with CI you can do programming in the way you want. Although it is recommended to keep to the structure, there will be times when we will need to do things the other way. With this structure we can accomplish two important things:

  • Loose Coupling: Coupling is the degree by which the components of a system rely on each other. The less the components depend on each other, the more reusable and flexible the system becomes.
  • Component Singularity: Singularity is the degree by which components have a narrow focus. In CI, each class and its functions are highly autonomous in order to allow maximum usefulness.

But how does all this work?

Now that we have seen how CI is structured, maybe you are asking yourself—how are the files in those three folders (models, views, controllers) working together? To answer this question we have another diagram, here it is:

But how does all this work?

As you can see it's similar to the previous one, and a little summarized (but with a wider scope of things, this is how the MVC pattern works), but this time we can see some new elements, and if you look at it closely you will be able to distinguish the flow of data. Let's explain it. First of all there is a browser call to your site, then the index.php file in the root folder is called (because we removed it from the URL, using the .htaccess file, we don't see it). This file acts as a router and calls the controllers, as and when they are needed. The controllers, as they are called, come into action. Now, two things can happen:

  • There is no need to fetch data from the database—in this case only the View is called, and loaded by the Controller. Then it is returned to the Browser for you or your visitors to see.
  • There is the need to fetch some data from the database—in this case the Controller calls the Model, which in turn makes a query to the database. The database returns data to the Model, and the Model to the Controller. The Controller modifies the data in every necessary way. Then it loads the View, passing all necessary data to it, and the View is created and returned to the Browser again.

Note

Do not get confused with the first case; there will be times when you will need to create static pages. CI doesn't differentiate between static and dynamic pages. On those occasions simply don't create the Models.

Now, return to our sample site to see how all this applies to it. Remember when we put the URL as http://127.0.0.1/codeigniter, CI's welcome screen appeared in our browser. Now try this URL http://127.0.0.1/codeigniter/welcome.

If you didn't follow the last few steps of Chapter 2 (or your hosting service doesn't support .htacces files)try using this URL: http://127.0.0.1/codeigniter/index.php/welcome.

In both cases the welcome screen appears in the browser. You maybe wondering, how CI knows, if you put http://127.0.0.1/codeigniter/, that it has to load the welcome controller. Don't worry, we will see that in a moment; for now, we will go on with our example:

http://127.0.0.1/codeigniter/index.php/welcome

A request coming to your website's root is intercepted by the index.php file, which acts as a router. That is, it calls a controller—welcome controller—which then returns a view, just as in the previous diagram. But how does the controller do that? We are going to see how in the welcome controller.

The welcome controller

As we know the welcome controller is the default controller, configured in the routes.php file of the config directory and the code is at ./application/controllers/welcome.php. Here's what it says:

<?php
class Welcome extends Controller { function Welcome() { parent::Controller(); } function index() { $this->load->view('welcome_message');
}
}
/* End of file welcome.php */ /* Location: ./system/application/controllers/welcome.php */

From the second line you'll learn that this file is a class. Every controller inherits from an original Controller class, hence extends Controller. The next three lines make the constructor function. Within the class there are two functions or methods—Welcome() and index().

Tip

Though it is not necessary, naming controllers the same way as for tables is a good practice. For example, if I have a projects table I will create a projects controller. You can name your controllers the way you want, but naming them like the tables they represent keeps things organized. Also, getting used to this won't harm you, as other frameworks are stricter about this.

Notice that CI uses the older PHP 4 convention for naming constructor functions, which is also acceptable by PHP 5—it doesn't require you to use PHP 5 and is happy with either version of the language. The constructor function is used to set up the class each time you instantiate it. We can obviate this and the controller will still work, and if we use it, it won't do any harm. Inside it we can put instructions to load other libraries or models, or definitions of class variables.

So far the only thing inside the constructor is the parent::Controller(); statement. This is just a way of making sure that you inherit the functionality of the Controller class. If you want to understand the parent CI Controller class in detail, you can look at the file /www/CI_system/libraries/controller.php.

Note

One of the reassuring things about CI is that all the code is there for you to inspect, though you don't often need to.

Working with views

Let's go back to the incoming request for a moment. The router needs to know which controller and which function within that controller should handle the request. By default the index function is called if the function is not specified. So, when we put http://127.0.0.1/codeigniter/welcome/, the index function is called. If no error is shown, this function simply loads the view, welcome_message using CI's loader function ($this->load->view). At this stage, it doesn't do anything cool with the view, such as passing dynamic information to it. That comes in later.

The welcome_message it wants to load, is in the views folder that you have just installed at www/codeigniter/application/views/welcome_message.php. This particular view is only a simple HTML page, but it is saved as a PHP file because most views have PHP code in them (no point in doing all this if we're only going to serve up plain old static HTML).

Here's the (slightly shortened) code for the view:

<html>
<head>
<title>Welcome to CodeIgniter</title>
<style type="text/css">
body
{
background-color: #fff;
margin: 40px;
font-family: Lucida Grande, Verdana, Sans-serif;
font-size: 14px;
color: #4F5155;
}
. . . . . more style information here . . . .
</style>
</head>
<body>
<h1>Welcome to CodeIgniter!</h1>
<p>The page you are looking at is being generated dynamically by CodeIgniter.
</p>
<p>If you would like to edit this page you'll find it located
at:
</p>
<code>system/application/views/welcome_message.php</code>
<p>The corresponding controller for this page is found at:</p>
<code>system/application/controllers/welcome.php</code>
<p>If you are exploring CodeIgniter for the very first time, you
should start by reading the <a href="user_guide/">User Guide</a>.
</p>
<p><br />Page rendered in {elapsed_time} seconds</p>
</body>
</html>

As you can see, it consists entirely of HTML, with an embedded CSS stylesheet. In this simple example, the controller hasn't passed any variables to the view.

Note

Curious about—<p><br />Page rendered in {elapsed_time} seconds</p>? Take a look at: http://codeigniter.com/user_guide/libraries/benchmark.html.

You can name the views the way you want, and don't put the .php extension for them. You will have to specify the extension when loading them, for example:

$this->load->view('welcome_message.html');

The default controller

A few moments ago we were wondering how it was possible that when we put http://127.0.0.1/codeigniter/, the welcome controller was called. Well, no magic there, it is all in /www/codeigniter/application/config/routes.php; open that file and take a look. Read it till you find this line:

$route['default_controller'] = "welcome";

This line tells CI which controller to call, if it is not specified in the URL. Don't misunderstand this, if you pass a wrong URL the default controller won't be called, it's only called if no other controllers are specified. Usually it is used to load the controller that contains the functions that create our index page; after that our application or website will provide our visitors with some kind of navigation.

In this case we are not specifying the function, so the index one will be called, but we could put another one if we want, such as:

$route['default_controller'] = "welcome/myfriend";

In this case we are calling the myfriend function inside the welcome controller. Can you think of more uses of the router file? Let's see one more. Suppose you have a long URL, we are going to use this as an example—http://127.0.0.1/codeigniter/welcome/myfriend/23.

If we add this line of code in the routes.php file:

$route['john'] = "welcome/myfriend/23";

From now on, if you put into your browser http://127.0.0.1/codeigniter/john you will end up seeing the result of the welcome controller, function myfriend with a parameter with value 23.

As we said, by default, the index function is called if no other is passed. You can alter this default if you like, by including a function called _remap($function). Where $function is the function, in the controller(s), you want to intercept and redirect. The function _remap always gets called first, irrespective of what the URL says.

For example, if we have called http://127.0.0.1/codeigniter/welcome/hello and our welcome controller looks this way:

<?php
class Welcome extends Controller
{
function Welcome()
{
parent::Controller();
}
function _remap($method)
{
if ($method == 'hello')
{
$this->say_hello();
}
else
{
$this->$method();
}
}
function say_hello()
{
echo "Hello";
}
function index()
{
$this->load->view('welcome_message');
}
}
/* End of file welcome.php */
/* Location: ./system/application/controllers/welcome.php */

Note

Take this last example as a demonstration of the _remap method. But don't try to use it in a real-world application, as more work needs to be put here.

The _remap function $method will be called instead of the hello function passed in the URL. This part of the URL would instead be passed as a parameter to the _remap function. Once inside we can use this parameter in our logic, for example, this time if we receive hello, we call the say_hello function. In other case we call the function passed as a parameter, so if we have the URL http://127.0.0.1/codeigniter/welcome/hello, the function say_hello will be called. If we have http://127.0.0.1/codeigniter/welcome/index, then the index function will be called.

Note

Have you noticed the underscore "_" before the function name remap? You can use it in your own functions. This way they will be only accessible by other functions inside the controller, but not from outside. That said, the following won't work: http://127.0.0.1/codeigniter/welcome/remap

CodeIgniter syntax rules

Before we start, let's just summarize the syntax rules that CI uses. The framework expects files to be set up in a certain way, otherwise it may have difficulty indentifying your files properly, or using them.

Controller

This is a class (that is OO code). It is called directly by the URL, for example, www.example.com/index.php/start/hello. Controllers are used to call functions by name, for example, mainpage(). However, within a controller you cannot call functions inside another controller. If you need to do such a thing, the functions common to both the controllers can be converted into a library or helper.

Syntax:

Controllers begin with class Start extends Controller (where the name of the controller has the first letter in uppercase) and are saved as a .php file in the /application/controllers folder. When saved, they should not have the first letter in uppercase, as in start.php and not Start.php. Also, they can include a constructor containing at least:

function Start()
{
parent::Controller();
}

All other code must be written as separate functions within the class, for example, a hello() function.

View

Views are HTML files that can contain PHP "islands". Here we place all the HTML code needed to create our site's pages. This is what our site's users are going to see. We place all our data, retrieved by our models and prepared by our controllers here. We can consider the views as the final stage of our data. They are loaded by $this->load->view('testview', $data). Loading and using the view are done in the same action.

Syntax:

The view is written in HTML. The PHP code is included within <?php ?> tags, as with any HTML file. It is saved as a .php file in the views folder.

Types of files or classes on a CI site

There are several sub-folders within the application folder. We have already looked at the controllers, config, and views folders.

But what are libraries, helpers, and plugins? In a technical sense, these folders are treated in much the same way. Let's say that you have written a block of code called display, which contains a function called mainpage. There are four ways you might have done this—as a model, a library, a helper, or a plugin. The following table summarizes the difference between each approach, and shows you how to load and use each type.

You could put your piece of new code in any of these folders, though you'd have to write it as an object-oriented class in the first two cases, as a procedural script in the second, and in the latter cases you wouldn't be able to draw directly on other CI classes.

Though we are not able to directly draw CI resources from within helpers and plugins, there's a way in which we can achieve that, using the get_instance(); method. Take a look at http://codeigniter.com/user_guide/general/creating_libraries.html. You will learn more about it, in Chapter 8.

You'll notice that CI can have two set of helpers, plugins, and libraries, though not of models. There can be one set of each in the application folder, and another set in the system folder. The difference, again, is largely conceptual as explained in the following:

  • Those in the system folder are intended to be part of the core CI code and to be shared by all applications. If you update to a later version of CI, then you will overwrite the system folder and these files may be modified.
  • Those in the application folder will only be available to that particular application. If you update to a new version of CI, the application folder will not be overwritten.
  • When you try to load a helper, plugin, or library, CI sensibly looks in both paths. If you attempt to load a library called display, for example, CI will first look in your system/application/libraries directory. If the directory does not exist or the display library is not there, CI will then look in the system/libraries folder.
  • It is possible to effectively overwrite CI's core libraries, helpers, and plugins by introducing your own with the same names in the applications folder. Don't do this accidentally. However, this flexibility is a great advantage for experienced CI users; if you want to extend the basic classes and scripts that come with CI, see Chapter 13.

Designing a better view

At this stage, you might ask: Why are we going through so much effort to serve a simple HTML page? Why not put everything in one file? For a simple site, that's a valid point—but whoever heard of a simple site? One of the coolest things about CI is the way it helps us to develop a consistent structure. So, as we add to and develop our site, it is internally consistent, well laid out, and simple to maintain.

At the start, we need to take these three common steps:

  • Write a view page
  • Write a stylesheet
  • Update our config file to specify where the stylesheet is

After this is done, we need to update our controller to accept parameters from the URL, and pass variables to the view.

First, let's redesign our view and save it as testview.php, at /www/codeigniter/application/views/testview.php.

<html>
<head>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN'http:\/\/www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
<html xmlns='http:\/\/www.w3.org/1999/xhtml'>
<title>Web test Site</title>
<link rel="stylesheet" type="text/css" href="<?php echo $base."/".$css;?>">
</head>
<body>
<h1><?php echo $mytitle; ?> </h1> <p class='test'> <?php echo $mytext; ?> </p>
</body>
</html>

It's still mostly HTML, but notice the PHP "code islands" in the highlighted lines. You'll notice that the first bits of PHP code build a link to a stylesheet. Make a folder named css in the root folder (codeigniter/css) and save a simple stylesheet as style.css. It just says:

h1
{
margin: 5px;
padding-left: 10px;
padding-right: 10px;
background: #ffffff;
color: blue;
width: 100%;
font-size: 36px;
}
.test
{
margin: 5px;
padding-left: 10px;
padding-right: 10px;
background: #ffffff;
color: red;
width: 100%;
font-size: 36px;
}

This gives us two styles to play with, and you'll see we've used both of them in the view. Firstly, let's add an entry to the config file:

$config['css'] = 'css/styles.css';

This is simply to tell the name and address of the CSS file that we've just written to the site. But note that the link to the stylesheet is referenced at $base/$css: Where do those variables, $base and $css, get their values? And come to think of those variables $mytitle and $mytext at the end of the code? We need a new controller!

Designing a better controller

Now, we need a new controller. We'll call it Start and save it as start.php, at /www/codeigniter/application/controllers/start.php.

This controller has to do several things:

  • Call a view
  • Provide the view with the base URL and the location of the CSS file we just wrote
  • Provide the view with some data—it's expecting a title ($mytitle) and some text ($mytext)
  • Lastly, accept a parameter from the user (that is using the URL request)

In other words, we have to populate the variables in the view. So let's start with our Start controller. This is an OO class:

<?php
class Start extends Controller
{
var $base;
var $css;

Notice that here we've declared the $base and $css (the CSS filename) as variables or class properties. This saves us from having to redeclare them if we write more than one function in each class. But you can define and use them as local variables within one function, if you prefer.

The constructor function now defines the properties we've declared, by looking them up in the config file. To do this, we use the syntax:

$this->config->item('name_of_config_variable');

As in:

function Start()
{
parent::Controller();
$this->base = $this->config->item('base_url');
$this->css = $this->config->item('css');
}

CI recovers whatever we entered in the config file against that name.

Using this system, no matter how many controllers and functions we write, we'll have to change these fundamental variables only once. This is true even if our site becomes so popular that we have to move it to a bigger server.

Getting parameters to a function

Now, within the Start controller class, let's define the function that will actually do the work:

function hello($name = 'Guest')
{
$data['css'] = $this->css;
$data['base'] = $this->base;
$data['mytitle'] = 'Welcome to this site';
$data['mytext'] = "Hello, $name, now we're getting dynamic!";
$this->load->view('testview', $data);
}

This function expects the parameter $name, but you can set a default value—myfunction($myvariable = 0)—which it uses to build the string assigned to the $mytext variable. Well, as we just asked, where does that come from?

In this case, it needs to come from the URL request, where it will be the third parameter. So, it comes through the HTTP request:

http://127.0.0.1/codeigniter/start/hello/Jose

Note

This example code doesn't "clean" the passed variable Jose, or check it in any way. You might want to do this while writing the code. We'll look at how to check form inputs in Chapter 5. Normally, variables passed by hyperlinks in this way are generated by your own site. A malicious user can easily add his or her own, just by sending a URL such as: http://www.mysite.com/index.php/start/hello/ my_malicious_variable. So, you might want to check that the variables you receive are within the range you expect, before handling them.

The last segment of the URL is passed to the function as a parameter. In fact, you can add more segments of extra parameters if you like, subject to the practical limits imposed by your browser.

Let's recap on how CI handles URLs, since we've covered it all now:

Passing data to a view

Let's go back to the hello function:

function hello($name)
{
$data['css'] = $this->css;
$data['base'] = $this->base;
$data['mytitle'] = 'Welcome to this site';
$data['mytext'] = "Hello, $name, now we're getting dynamic!";
$this->load->view('testview', $data);
}

Notice how the hello() function first creates an array called $data, taking a mixture of object properties set up by the constructor and text. Then it loads the view by name, with the array it has just built as the second parameter.

Behind the scenes, CI makes good use of another PHP function—extract(). This takes each value in the $data array and turns it into a new variable in its own right. So, the $data array that we've just defined is received by the view as a series of separate variables; $text (equal to"Hello, $name, now we're getting dynamic"), $css (equal to the value from the config file), and so on. In other words, when built, the $data array looks like this:

Array
(
[css] => 'mystyles.css';
[base] => 'http://127.0.0.1/packt';
[mytitle] => 'Welcome to this site';
[mytext] => 'Hello, fred, now we're getting dynamic!';
)

But on its way to the view, it is unpacked, and the following variables are created in the view to correspond to each key/value pair in the array:

$css = 'mystyles.css';
$base = 'http://127.0.0.1/packt';
$mytitle = 'Welcome to this site';
$mytext = 'Hello, fred, now we're getting dynamic!';

Although you can only pass one variable to a view, you can pack a lot of information into it. Each value in the $data array can itself be another array, so you can pass pieces of information to the view in a tightly structured manner.

Now navigate to http://127.0.0.1/codeigniter/start/hello/jose (note that the URL is different—it is looking for the start function we wrote in the index controller) and you'll see the result—a dynamic page written using MVC architecture (well, VC at least! We haven't really used the M yet).

You can see that the parameter jose is the last segment of the URL. It has been passed into the function, and then to the view. Please remember that your view must be written in parallel with your controller. If the view does not expect and make a place for a variable, it won't be displayed. If the view is expecting a variable to be set and it isn't, you are likely to get an error message (your view can of course accept variables conditionally).

Also, a controller can use more than one view; this way we can separate our pages into sections such as the header, the menu, and so on. Each of these views can be nested one inside the other. Child views can even inherit variables passed by the controller to their parent view.

Loading a view from inside another view is very easy; just put something like the following PHP snippet in your HTML code:

<body>
<div id="menu">
<?php $this->load->view('menu'); ?>

This way we can load a view inside a view, with all variables in the first one also available into the nested one. We will see more about this in Chapter 5.

How CI classes pass information and control to each other

As you write your controllers, models, and so on, you will need to pass control and data between them. Let's look at some of the ways in which we can do this.

Calling views

We have seen how the controller calls a view and passes data to it.

First it creates an array of data ($data) to pass to the view, loads it, and calls the view in the same expression:

$this->load->view('testview', $data);

Calling functions directly

If you want to use code from libraries, models, plugins, or helpers, you have to load them first, and then call them as described in the previous table. So, if display is a model and I want to use its mainpage function, my controller might call:

$this->display->mainpage();

If the function requires parameters, we can pass them to the function like this:

$this->display->mainpage('parameter1', $parameter2);

Interacting with controllers

You can call libraries, models, plugins, or helpers from within any controller, or model; libraries, plugins, and helpers can also call each other.

However, you can't call one controller from another, or a controller from a model or library. There are only two ways in which a model or a library can refer back to a controller:

  • It can return data if the controller assigns a value such as this:
    $fred = $this->mymodel->myfunction();

    Using this, the function is set to return a value, which will be passed to the variable $fred inside the controller.

  • Your model or library can create (and send to a view) a URL, which allows a human user to call the controller functions. Controllers are there to receive human interactions.

You can't, of course, hyperlink directly to a model or library. Users always talk to controllers, never to anything else; however, you can write a calling function in the controller. In other words, your view might contain a hyperlink to a controller function:

echo anchor('start/callmodel', 'Do something with a model');

The callmodel function would exit only to call a function in the model:

function callmodel()
{
$this->load->model(mymodel);
$this->mymodel->myfunction();
}

An example of a CI helper—the URL helper

As an example you can split your code into neat, focused chunks. CI's URL helper contains a set of functions that help you to manipulate URLs. You load it like this:

$this->load->helper('url');

You can also use it to find and return the site and/or base URLs that you set in your config file:

echo site_url();
echo base_url();

You can also use it to create hyperlinks. In the last section, we saw how to access the hello function in the start controller and pass the parameter fred to it, with a URL such as:

http://www.mysite.com/index.php/start/hello/fred

If you want your code to create a hyperlink to a URL, you can use the URL helper to do it. The syntax is:

echo anchor('start/hello/fred', 'Say hello to Fred');

This generates a hyperlink to the same URL, and displays the words Say hello to Fred for the user to click on. In other words, it's an equivalent of:

<a >Say hello to Fred</a>

Remember, there are two advantages to using the CI helper. Firstly, less typing required—49 characters as opposed to 82, both including spaces. If you include another 27 characters loading the URL helper, which you have to do once per controller, it still comes to 76 rather than 82.

Secondly, the URL helper automatically looks up the site URL in the config files (and the index file name). This means that if you change your site location, you only need to alter the config file once. You don't have to hunt through your code for hyperlinks that don't work any more.

The URL helper has other useful functions. For instance, it can create a mailto hyperlink such as:

echo mailto('me@example.com', 'Click Here to Email Me');

It has the same effect as typing this HTML:

<a href="mailto:me@example.com">click here to email me</a>

If you are worried about robots harvesting the email addresses from your website and using them for spamming, change mailto in the CI code to safe_mailto. What appears on your viewer's screen is exactly the same, and works the same way.

However, if you examine the actual HTML code, this has now become a complex heap of JavaScript, which the robot cannot (easily) read:

<script type="text/javascript">
//<!
[CDATA[
var l=new Array();
l[0]='>';l[1]='a';l[2]='/
';l[3]='<';l[4]='|101';l[5]='|109';l[6]='|32';l[7]='|108';l[8]='|105';l[9]='|97';l[10]='|109';l[11]='|101';l[12]='|32';l[13]='|111';l[14]='|116';l[15]='|32';l[16]='|101';l[17]='|114';l[18]='|101';l[19]='|72';l[20]='|32';l[21]='|107';l[22]='|99';l[23]='|105';l[24]='|108';l[25]='|67';l[26]='>';l[27]='"';l[28]='|109';l[29]='|111';l[30]='|99';l[31]='|46';l[32]='|101';l[33]='|108';l[34]='|112';l[35]='|109';l[36]='|97';l[37]='|120';l[38]='|101';l[39]='|64';l[40]='|101';l[41]='|109';l[42]=':';l[43]='o';l[44]='t';l[45]='l';l[46]='i';l[47]='a';l[48]='m';l[49]='"';l[50]='=';l[51]='f';l[52]='e';l[53]='r';l[54]='h';l[55]=' ';l[56]='a';l[57]='<';
';l[3]='<';l[4]='|101';l[5]='|109';l[6]='|32';l[7]='|108';l[8]='|105';l[9]='|97';l[10]='|109';l[11]='|101';l[12]='|32';l[13]='|111';l[14]='|116';l[15]='|32';l[16]='|101';l[17]='|114';l[18]='|101';l[19]='|72';l[20]='|32';l[21]='|107';l[22]='|99';l[23]='|105';l[24]='|108';l[25]='|67';l[26]='>';l[27]='"';l[28]='|109';l[29]='|111';l[30]='|99';l[31]='|46';l[32]='|101';l[33]='|108';l[34]='|112';l[35]='|109';l[36]='|97';l[37]='|120';l[38]='|101';l[39]='|64';l[40]='|101';l[41]='|109';l[42]=':';l[43]='o';l[44]='t';l[45]='l';l[46]='i';l[47]='a';l[48]='m';l[49]='"';l[50]='=';l[51]='f';l[52]='e';l[53]='r';l[54]='h';l[55]=' ';l[56]='a';l[57]='<';
for (var i = l.length-1; i >= 0; i=i-1){
if (l[i].substring(0, 1) == '|') document.write("&"+unescape(l[i].substring(1))+";");
else document.write(unescape(l[i]));}
//]]>
</script>

You and your users need never see this code. It's only there to confuse the robots and keep your email addresses safe from spam. You put it there by adding four letters and an underscore, where you wrote safe_mailto instead of mailto, and CI did the rest.

There are several other useful functions in the URL helper. Take a look at the user guide, where you will find some helpful ones:

http://codeigniter.com/user_guide/helpers/url_helper.html

Just consider the URL helper as a whole. Let's go back to the touchstones for coding, which we discussed earlier in this chapter:

  • This code has high "component singularity". It does a limited range of things, and it's clear what they are.
  • It is "loosely coupled"—it has a simple interface and no dependency on any code that's calling it. You can use the URL helper in any CI project you're writing. Most of your projects will need some sort of hyperlinks. You can use this helper over and over again to create them.

If you look at the URL helper's code in /www/codeigniter/application/helpers/url_helper.php, you'll see that it is procedural code, that is, it is simply a set of functions, not an OO class. It doesn't load any other CI classes or helpers (not being an object it can't do this directly).

A simple library example—creating a menu

Now let's look at some code that uses the CI classes. For instance, here is a simple library file that creates a menu with three choices. You can save it in /www/codeigniter/application/libraries/menu.php:

1 <?php
2 class Menu{
3 function show_menu()
4 {
5 $obj =& get_instance();
6 $obj->load->helper('url');
7 $menu = anchor("start/hello/fred","Say hello to Fred |");
8 $menu .= anchor("start/hello/bert","Say hello to Bert |");
9 $menu .= anchor("start/another_function","Do something else |");
10 return $menu;
11 }
12 }
13 ?>

For the moment, don't worry about the unusual syntax—$obj-> rather than $this->, on line 6. This is explained in Chapter 7.

Note that this code is now OO code, in which the function show_menu() is contained in a single class, that is Menu. It can access other CI classes and helpers; in this case it is using the URL helper, which we just examined.

First it loads the URL helper and then it creates a string ($menu), consisting of HTML code for hyperlinks to the three controllers and functions specified. Then it returns the $menu string.

You might call it from a controller like this:

$this->load->library('menu');
$mymenu = $this->menu->show_menu();

The controller can then use the $menu variable to call a view:

$data['menu'] = $mymenu;
$this->load->view('myview', $data);

After that you will only have to put echo $menu in your view file, which will produce a site-specific menu. For this reason, we have saved it in the /www/codeigniter/application/libraries, rather than the /CI_system/libraries folder. It's not as loosely coupled as the URL helper, which I can use on any site.

It does have high singularity—it creates a menu, and that's all it does. It can be called from any controller in the site and it will show the standard menu in the view.

主站蜘蛛池模板: 山阳县| 余姚市| 辛集市| 衡阳县| 大安市| 理塘县| 西宁市| 新蔡县| 陆川县| 永嘉县| 华安县| 会东县| 白玉县| 抚顺市| 韩城市| 惠来县| 新余市| 滨海县| 普洱| 弥勒县| 三门峡市| 宝清县| 房山区| 宝兴县| 连云港市| 靖西县| 全椒县| 静宁县| 搜索| 电白县| 三江| 浦县| 盐池县| 东兴市| 荃湾区| 新余市| 德兴市| 中阳县| 潢川县| 西城区| 花莲县|