【问题标题】:How do I make this code reusable on different views? Proper method如何使此代码可在不同视图上重用?正确的方法
【发布时间】:2012-09-19 20:23:30
【问题描述】:

我对执行以下操作的正确方法有些困惑。这是一个类,一个函数还是一个对象? (不确定)所以这里(请善待)我正在同时学习 codeigniter/php。

    $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>'; 

我编写了这段代码,它检查是否设置了会话,如果为真,则回显详细信息。我目前在我的view/main 上有此代码但是我希望在所有页面上显示此代码。

这样做的正确方法是什么?

  1. 我是否要创建一个view/header,它会自动加载到每个页面上,然后在其中插入这个code
  2. 我是否在helper 文件中创建class/public function 并将其加载到需要的位置?
  3. 是否在library 文件中创建class/public function 并将其加载到需要的位置?
  4. 我是否在控制器中创建public function

-额外- 我的假设是选项1 但我很好奇如果我想在特定页面的另一个位置显示此信息怎么办?我不想复制/粘贴代码块,因为那太草率了。

我将如何设置它以便我可以在需要的地方调用它? 例如$this-&gt;load-&gt;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>'; 

    }
}

view我试过这个:

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

但是这不起作用并导致'函数 userdata() on a non-object error'

有人可以解释实现我想要的解决方案的正确方法和正确的语法吗?提前致谢!

-UPDATE-- 试图创建一个库 - 仍然出错。

#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');

--更新--

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>';
            }

    }

}

设置这个^是libraries文件夹

view 显示 &lt;?php echo $this-&gt;CheckSess-&gt;IsLive(); ?&gt;

controller 显示 $this-&gt;load-&gt;library('CheckSess');

请指教。再次感谢!

错误---

( ! ) SCREAM: 忽略错误抑制 ( ! ) 致命错误:在第 56 行的 C:\wampserver\www\test-app\application\views\homepage.php 中的非对象上调用成员函数 IsLive() 调用栈

时间记忆功能定位

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 包括('C:\wampserver\www\test-app\application\views\homepage.php')..\Loader.php:833

【问题讨论】:

  • 你有一些不安全和不稳定的代码,你的if() 没有else 部分,所以当你的条件失败时,你会得到一个错误,你正在尝试echo nothing .至少添加 } else { echo ""; } 以使代码在各种情况下都能正常工作
  • 否则返回 false 怎么样? -----ERROR---- 遇到 PHP 错误严重性:通知消息:未定义属性:CI_Loader::$CheckSess 文件名:views/homepage.php 行号:50
  • 您真的要在视图文件中回显“false”吗?或者您应该在调用此方法时在视图文件中构建 if-then-else。此错误实际上表明加载库时出现问题,因此您应该查看它是否在相应的文件夹中并且所有名称都正确。尝试以这种方式加载库:$this-&gt;load-&gt;library('CheckSess', '', 'checksess');,然后像$this-&gt;checksess-&gt;isLive()一样使用它
  • 是的,有效。 - 你怎么能这么快破译那个错误。我发现错误消息有些晦涩。我按照libraries 的命名说明到了一个 T - 不知道为什么必须在控制器中这样重命名它。谢谢!
  • codeigniter.com/user_guide/general/creating_libraries.html --> 命名约定 "文件名必须大写。例如:Myclass.php 类声明必须大写。例如:class Myclass 类名和文件名必须匹配。"

标签: php oop codeigniter


【解决方案1】:

在 CodeIgniter 中编写此类可重用的最佳方法是模型和库。

使用库会更好,因为您使用的代码和逻辑实际上并不是 MVC 中的模型,但是使用 CodeIgniter,特别是对于初学者,如果您不打算分发或共享,则可以在模型中编写它任何方式的这段代码。

我建议阅读更多关于 CodeIgniter 中哪些内容的信息,您可以在此处、SO 或官方 CI 论坛上找到大量信息,但作为快速参考,我会写一份内容清单。

观看次数

静态、哑数据输出、格式化、迭代(用于显示表格、列表等)。

你想在这里使用的只是一些基本的 PHP 函数、CodeIgniter 助手、forforeachwhile 循环和条件(ifcase

控制器

表单数据捕获和验证,从模型中捕获数据,将数据发送到视图,重定向。

型号

从数据库、远程源 (API)、文件中查询、读取、写入和更新数据。

助手

预计将在视图中使用的常用函数 - 格式化 HTML,将树解析和显示为列表 &lt;ul&gt;&lt;li&gt;&lt;/li&gt;&lt;/ul&gt;,其他函数的简写函数,如

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

不使用任何 CodeIgniter 库/模型的东西(技术上它可以使用,但在大多数情况下应该避免使用)。

自定义类和对象、数据处理、API 接口、上述的复合体



如果你想显示一些带有数据的视图文件,我会把它放在一个库中。您可以将其放入模型中。在我的项目中,当我使用某些部件时,我有一个库/模型(在我们的案例中差异很小),我们称之为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>'; 

    }
}

现在,如果您之前加载过视图文件中的任何位置,您都可以调用 $this-&gt;pmodel-&gt;ShowMyPart()(这种类型的模型无论如何都应该自动加载)。

我会做一些小改动,因为这被认为是一种好的做法 - 除了视图文件之外,从任何地方都不要 echo 任何东西,而是 return 值。

echo 关键字更改为 return 并在您的视图文件中简单地写 echo $this-&gt;pmodel-&gt;ShowMyPart()

为什么要这样做?因为,如果您想在加载页眉和页脚(例如)之间调用任何从控制器回显某些内容的方法,CodeIgniter 将在页眉之前回显此内容,因为 CodeIgniter 不会立即回显您加载的视图,它会将它们保存到输出存储并在销毁自己之前发送最终输出。更多阅读可以找到here

但您可以做得更好 - 使用视图文件输出您想要的任何数据,只需创建一个帮助程序并从您的模型/库中加载它,就像您在控制器中所做的那样。

希望有帮助!


编辑

对于您编辑的问题,您的库出现错误的原因是您的库不知道 CodeIgniter 的实例甚至存在,因为您没有从它扩展您的库,就像您对模型和控制器。您不要使用 $this 来引用库中的 CodeIgniter 类,因为 $this 是对您的库本身的引用,它是一个单独的类。要使用 CodeIgniter 类,您应该获得一个 CodeIgniter 实例:

$CI =& get_instance();

然后你可以使用$CI而不是$this通过更改行来调用CodeIgniter类:

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

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

【讨论】:

  • 嘿,我非常感谢您的回复 - 感谢您抽出宝贵时间撰写如此详尽的回复。当你写这篇文章时,我更新了我的问题,认为图书馆是正确的方法。请查看我修改后的代码和您认为合适的评论。还有我在课堂上写什么? class CheckSess extends ...我按照创建正确库的语法(大写和匹配名称)创建了文件你有什么想法?
【解决方案2】:

您可以制作一个基本的 html 帮助程序并将其自动加载到配置文件中。

那你可以为此做一个函数……

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;
}

然后你把它当作一个普通函数来调用:

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

但理想情况下,您应该将这样的内容放在包含标准页面视图的模板或头文件中。没有必要用这样的东西来做一个功能,因为通常你没有在页面上的多个地方登录/注销。 可以简化为:

<?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; ?>

我更喜欢制作网站模板并用它包装视图。使通用元素更容易处理。 有些人以这种方式对其进行模板化: http://codeigniter.com/forums/viewthread/88335/

有很多方法可以处理这个问题,但总体思路是将最常见的元素分离到一个模板视图中。我不知道有一种简洁的方式来指导您如何执行此操作,因此只有在您觉得需要对模板进行更多解释时,我才会更新这篇文章。

帮助文档: http://codeigniter.com/user_guide/general/helpers.html

【讨论】:

  • 别忘了,你不能在助手中使用$this,请参阅我的回答中的编辑以了解原因
  • 感谢您的建议和意见。你提供了一个很好的例子和可能的解决方案。问这个问题我是在寻求“行业标准”的答案——但是从你的两个回复中,我觉得解决方案真的取决于编码人员的个人偏好(只要组织保持一致)所以公平吗?假设从性能的角度来看,任何一种解决方案都会和另一个一样好? @Vlakarados 我尝试了您更新的代码修改,但我仍然收到错误。我会更新我的代码——如果你不介意请查看。谢谢
  • @fabio 我会尽力提供帮助,但你应该包括你自己得到的错误,因为我猜不出那里出了什么问题 =) 无论如何 - 是的,这是一个偏好问题,我们刚刚提供了一些可能性,我们根据自己的经验更好地工作 =)
  • 请记住,虽然最好有一个整洁有序的编程偏好,但最终这些方法中的任何一种都不太可能以明显的方式影响性能。如果您从事企业级工作,那么这很重要,并且您希望尽可能高效,但是对于标准人员/客户使用的大多数网站,我不会太担心这样的基准。
猜你喜欢
  • 1970-01-01
  • 2012-05-22
  • 2018-04-12
  • 1970-01-01
  • 1970-01-01
  • 2020-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多