How do I make this code reusable on different view

2019-06-08 01:10发布

问题:

I am somewhat confused on the proper way to perform the following. Is this a class a function or an object? (Not sure) So here goes (please be kind) I'm learning codeigniter/php simultaneously.

    $is_live = $this->session->userdata('email');
    $is_live = ucwords($is_live);
            if (!$is_live == null)
                   echo 'Hello, '.$is_live.
                   ' <b>(Not you? '.'<a href="' .base_url().
                   'main/logout">Log Out</a>) </b>'; 

I wrote this code, which checks if a session is set and if true echo the details. I currently have this code on my view/main However I want to have this code displayed on all pages.

What is the proper way to do this?

  1. Do i create a view/header which is auto loaded on each page and insert this code there?
  2. Do I create a class/public function in a helper file and load it where needed?
  3. Do I create a class/public function in a library file and load it where needed?
  4. Do I create a public function in a controller?

-EXTRA- My assumption is option 1 but I'm curious what if I want to display this information in another location on a particular page? I don't want to have to copy/paste the code block because that is sloppy.

How would I set it up so that I can just call it where i need it? e.g. $this->load->helper('check_for_sess');

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class isLive
{   
    public function is_live() {

        $is_live = $this->session->userdata('email');
        $is_live = ucwords($is_live);
             if (!$is_live == null)
               echo 'Hello, '.$is_live.
               ' <b>(Not you? '.'<a href="' .base_url().'main/logout">Log Out</a>) </b>'; 

    }
}

On the view I tried this:

<?php 
    $isLive = new isLive;
    $isLive->is_live(); 
?>

This however doesn't work and causes a ' function userdata() on a non-object error '

Can someone please explain the proper way to achieve my desired solution and the correct syntax. Thanks in advance!

-UPDATE-- Tried to create a library - still getting error.

#Created a library 
class CheckSess 
{   
    function IsLive() 
    {   
    $is_live = $this->session->userdata('email');
    $is_live = ucwords($is_live);

            if (!$is_live == null) 
            {
               $check_msg = 'Hello, '.$is_live.
               ' <b>(Not you? '.'<a href="' .base_url().'main/logout">Log Out</a>) </b>';
            }

    return $check_msg;
    }

}


#In the View
<?php echo $this->CheckSess->IsLive();  ?>

#in the controller
$this->load->library('CheckSess');

--UPDATE--

class CheckSess {

    function IsLive() 
    {   
    $CI =& get_instance();
    $is_live = $CI->session->userdata('email');
    $is_live = ucwords($is_live);

            if (!$is_live == null) 
            {
               return 'Hello, '.$is_live.
               ' <b>(Not you? '.'<a href="' .base_url().'main/logout">Log Out</a>) </b>';
            }

    }

}

Set this^ is the libraries folder

the view shows <?php echo $this->CheckSess->IsLive(); ?>

and the controller shows $this->load->library('CheckSess');

please advise. Thanks again!

ERROR---

( ! ) SCREAM: Error suppression ignored for ( ! ) Fatal error: Call to a member function IsLive() on a non-object in C:\wampserver\www\test-app\application\views\homepage.php on line 56 Call Stack

Time Memory Function Location

1 0.0005 151432 {main}( ) ..\index.php:0 2 0.0014 187792 require_once( 'C:\wampserver\www\test-app\system\core\CodeIgniter.php' ) ..\index.php:202 3 0.0277 1537000 call_user_func_array ( ) ..\CodeIgniter.php:359 4 0.0277 1537048 Main->index( ) ..\CodeIgniter.php:359 5 0.0283 1540200 CI_Loader->view( ) ..\main.php:8 6 0.0283 1540640 CI_Loader->_ci_load( ) ..\Loader.php:419 7 0.0287 1566584 include( 'C:\wampserver\www\test-app\application\views\homepage.php' ) ..\Loader.php:833

回答1:

The best ways to write such reusable in CodeIgniter are Models and Libraries.

With libraries being better because the code and logic you use isn't actually what models in MVC are, but with CodeIgniter and especially for a beginner it's pretty much ok to write this in models if you are not planning to distribute or share this code in any way.

I would suggest reading more on what goes where in CodeIgniter, you can find plenty information here, on SO or on official CI forums, but as a quick reference, I will write a list of what goes where.

Views

Static, dumb data output, formatting, iteration(for displaying tables, lists, etc.).

The only things you want to use here are some of the basic PHP functions, CodeIgniter helpers, for, foreach, while loops and conditionals (if, case)

Controllers

Form data capture and validation, catching data from models, sending data to views, redirects.

Models

Querying, reading, writing and updating data from databases, remote sources (APIs), files.

Helpers

Often used functions that are expected to be used in views - formatting HTML, parsing and displaying trees as lists <ul><li></li></ul>, shorthand functions for other functions like

function mydate() {
    return date("d.m.Y");
}

Stuff that does not use any of the CodeIgniter libraries/models (Technically it can use, but should be avoided in most cases).

Libraries

Custom classes and objects, data processing, API interfaces, complex of the aforementioned



If you want to display some view file with data, I would put it in a library. You can put it in to a model. In my projects when I use some parts, I have a library/model (difference in our case is minimal), lets call it pmodel.

class Pmodel extends CI_Model() {
    function ShowHeader() {
        $data = array(
            'user' => $this->usermodel->GetCurrentUser()
        }
        $this->load->view('header', $data);
    }

    function ShowMyPart() {
        $is_live = $this->session->userdata('email');
        $is_live = ucwords($is_live);
        if (!$is_live == null)
               echo 'Hello, '.$is_live.
               ' <b>(Not you? '.'<a href="' .base_url().
               'main/logout">Log Out</a>) </b>'; 

    }
}

Now anywhere in the view files you can call $this->pmodel->ShowMyPart() if you have loaded it before (models of this type should be autoloaded anyway).

There is one little change I would do as it's considered as good practice - never echo anything from anywhere but the view files, return values instead.

Change the echo keyword to return and in your view file simply write echo $this->pmodel->ShowMyPart().

Why should you do that? Because, if you would like to call any method that echoes something from the controller right between loading header and footer(eg.), CodeIgniter will echo this before the header as CodeIgniter does not echo your loaded views right away, it saves them to output storage and sends the finalized output right before destructing himself. More reading can be found here.

But you can do even better - use a view file to output any data you want, just create a helper and load it from your model/library as you do in your controllers.

Hope that helps!


EDIT

For your edited question, the reason why you are getting errors with your library is that your library doesn't know that an instance of CodeIgniter even exists as you are not extending your library from it, as you do with your models and controllers. You don't use $this to refer to CodeIgniter classes in your libraries, as $this is a reference to your library itself, which is a separate class. To use CodeIgniter classes you should get a CodeIgniter instance:

$CI =& get_instance();

And then you can use $CI instead of $this to call CodeIgniter classes by changing the line:

$is_live = $this->session->userdata('email');

to

$is_live = $CI->session->userdata('email');


回答2:

You could make a basic html helper and autoload it in the config file.

Then you can make a function for this...

function displayLoginStatus($em)
{ 
    $html = '';
    if($em)
    {
        $html = 'Hello, '.ucwords($em).' <b>(Not you? '.'<a href="' .base_url().'main/logout">Log Out</a>) </b>';
    }

    return $html;
}

then you call it like a normal function:

<?php echo displayLoginStatus($this->session->userdata('email')); ?>

but ideally you would place something like this in a template or header file that wraps your standard page views. There's no need to make a function out of something like this since typically you don't have the login / logout in multiple places on the page. It could be condensed simply to:

<?php if($this->session->userdata('email')): ?>
Hello, <?php echo ucwords($this->session->userdata('email')); ?> <b>(Not you? <a href="<?php echo base_url(); ?>main/logout">Log Out</a>) </b>
<?php endif; ?>

I prefer to make a site template and wrap the views with it. Makes common elements much easier to handle. Some people template it this way: http://codeigniter.com/forums/viewthread/88335/

There are many ways you could handle this, but the general idea is to separate your most common elements into one template view. I don't know of a succinct way of instructing you on how to do this so I will only update this post if you feel the need for much more explanation on templating.

helper docs: http://codeigniter.com/user_guide/general/helpers.html