du970294 2012-12-28 19:47
浏览 38

将对象从全局范围传递到模型

Here's the code of my model in codeigniter.

<?php

$catalogo = (object) array (
    "name" => "catalogo",
    "url" => "url_catalogo"
);
$categorias = (object)array (
    "name" => "categorias",
    "titulo" => "varchar_titulo",
);

$novedades = (object)array (
    "name"      => "novedades",
    "titulo"    => "varchar_titulo",
    "fecha"     => "fecha_publicacion",
    "descripcion"   => "text_descripcion",
    "categoria" => "fk_categoria"
);

$img_nov =(object) array (
    "name"      => "imagenes_novedades",
    "url"       => "url_img",
    "novedad"   => "fk_novedad"
);  
$marcas = (object) array(
    "name"      => "marcas",
    "titulo"    => "varchar_titulo",
    "url"       => "url_imagen"
);
$img_slide  = (object) array (
    "name"  => "slide_destacados",
    "url"   => "url_img"
);

$users = (object) array (
    "db"    => "users",
    "user"  => "username",
    "pass"  => "password"
);
class Model extends CI_Model 
{

    function __construct()
    {
        parent::__construct();
    }

    function check_user ( $username, $password )
    {
        global $users;
        if ( $username == "" || $password == "" )
            return FALSE;

        $hashed_password = md5( $password ); 

        $this->db->where($users->user, $username );
        $this->db->where($users->pass, $hashed_password );

        $query = $this->db->get($users->name);

        if ( $query->num_rows() > 0 )
            return TRUE;
        return FALSE;
    }

    /*
     * Slide de destacados de la pagina principal.
     * no creo que necesitemos mas que esto
     */

    function imagenes_slide ( $id = -1 )
    {
        global $img_slide;
        if ( $id == -1 )
            $this->db->where( 'id', $id);
        $query = $this->db->get( $img_slide->name);

        return $query->result_array();
    }

    function borrar_imagen_slide( $id )
    {
        global $img_slide;
        $image_to_delete = $this->imagenes_slide( $id );

        $this->db->where('id', $id);
        $this->db->delete($img_slide->name);

        return $image_to_delete[0][$img_slide->url];
    }

    function agregar_imagen_slide( $url )
    {
        global $img_slide;
        $this->db->insert( $img_slide->name, array( $img_slide->url => $url ));
    }

    function cambiar_imagen_slide ( $id, $url )
    {
        global $img_slide;
        $this->db->where( 'id', $id );
        $this->db->update( $img_slide->name, array( $img_slide->url, $url ) );
    }

    /*
     * Url del catalogo.
     */

    function url_catalogo( $id = -1 )
    {
        global $catalogo;
        if ( $id !== -1 )
            $this->db->where( 'id', $id );

        $query = $this->db->get( $catalogo->name );
        return $query->result_array();
    }

    function add_catalogo ( $url )
    {
        global $catalogo;
        $this->db->insert( $catalogo->name, array( $catalogo->url, $url) );
    }

    function remove_catalogo ( $id )
    {
        global $catalogo;
        $url_catalogo = $this->url_catalogo( $id );

        $this->db->where( 'id', $id );
        $this->db->delete( $catalogo->name );

        # Es solo que queremos el primero, ya que buscamos por id
        # y este es unico.
        return $url_catalogo[0][$catalogo->url];
    }

    function update_catalogo ( $id, $url )
    {
        global $catalogo;
        $this->db->where( 'id', $id );
        $this->db->update( $catalogo->name, array( $catalogo->url, $url ) );
    }

    /*
     * Marcas.
     */

    function get_marcas ( $id = -1)
    {
        global $marcas;
        if( $id !== -1 )
            $this->db->where( 'id', $id );
        $query = $this->db->get( $marcas->name );
        return $query->result_array();
    }   

    function add_marca ( $titulo, $url )
    {
        global $marcas;
        $n = array( $marcas->titulo => $titulo, $marcas->url => $url );
        $this->db->insert( $marcas->name, $n );
    }

    function remove_marca ( $id )
    {
        global $marcas;
        # Get the url to delete the image
        $url_to_delete = $this->get_marcas( $id );

        $this->db->where( 'id', $id );
        $this->db->delete( $marcas->name );

        # Es solo que queremos el primero, ya que buscamos por id
        # y este es unico.
        return $url_to_delete[0][$marcas->url];
    }

    function update_marca ( $id, $titulo = FALSE, $url = FALSE )
    {
        global $marcas;
        $to_update = array ();

        if ( $titulo != FALSE )
            $to_update[$marcas->titulo] = $titulo;
        if ( $url != FALSE )
            $to_update[$marcas->url] = $url;

        if ( $to_update !== array() )
        {
            $this->db->where( 'id', $id );
            $this->db->update($marcas->name, $to_update );
        }
    }

    /*
     * Categorias!
     */
    function get_categorias ( $id = -1 )
    {
        global $categorias;
        if ( $id != -1 )
            $this->db->where('id', $id);
        $query = $this->db->get( $categorias->name );
        return $query->result_array();
    }

    function remove_categoria ( $id )
    {
        global $categorias;
        # Conseguimos todos los items de las categorias.
        $novedades = $this->get_novedades( $id );
        foreach( $novedades as $novedad )
        {
            $this->delete_novedad ( $novedad["id"] );
        }

        $this->db->where( 'id', $id );
        $this->db->delete( $categorias->name );
    }

    function add_categoria ( $titulo )
    {
        global $categorias;
        $data = array( $categorias->titulo, $titulo );
        $this->db->insert ($categorias->name, $data);
    }

    function update_categoria ( $id, $titulo )
    {
        global $categorias;
        $this->db->where( 'id', $id);
        $this->db->update( $categorias->name, array( $categorias->titulo, $titulo ) );
    }

    /*
     * Novedades ! (Esto va a ser largo)
     */

    function get_novedades ( $id_categoria, $id_novedad = FALSE, $offset = FALSE )
    {
        global $novedades;
        $this->db->where( $novedades->categoria, $id_categoria );
        if ( $id_novedad !== FALSE )
            $this->db->where ( 'id', $id_novedad );
        if ( $offset !== FALSE )
            $this->db->limit( 10, $offset );
        $query = $this->db->get( $novedades->name );

        return $query->result_array();
    }

    function add_novedad ( $titulo, $descripcion, $id_categoria )
    {
        global $novedades;
        # Hay que crear la fecha actual.
        $date = new Date();

        $to_add = array (
            $novedades->titulo  => $titulo,
            $novedades->fecha   => $date,
            $novedades->descripcion => $descripcion,
            $novedades->categoria   => $id_categoria
        );
        $this->db->insert( $novedades->name, $to_add );
    }

    function delete_novedad ( $id )
    {
        global $novedades;

        # Y ahora sacamos de la base de datos.
        $this->db->where( 'id', $id );
        $this->db->delete( $novedades->name );

        # Retornamos todas las urls de las imagenes.
    }

    function update_novedad ( $id, $titulo = FALSE, $descripcion = FALSE )
    {
        global $novedades;
        $to_update = array();
        $this->db->where ( 'id' , $id );
        if ( $titulo != FALSE )
            $to_update[$novedades->titulo] = $titulo;
        if ( $descripcion != FALSE )
            $to_update[$novedades->descripcion] = $descripcion;

        if ( $to_update === array() )
            return FALSE;
        $this->db->update( $novedades->name, $to_update );
    }

    /*
     * Aca van las imagenes de las novedades.
     */

    function get_images_novedad ( $id_novedad, $amount = 0 )
    {
        global $img_nov;
        if ( $amount != 0 )
            $this->db->limit( $amount );
        $this->db->where( $img_nov->novedad, $id_novedad );
        $query = $this->db->get( $img_nov->name );

        return $query->result_array();
    }

    function delete_imagen_novedad ( $id )
    {

        global $img_nov;
        # Primero que nada, eliminamos todas las imagenes. :)
        $images = $this->get_imagenes_novedad ( $id );
        $to_delete_permantenlty = array();
        foreach ( $images as $image )
        {
            $to_delete_permantenlty[] = $image[$img_nov->url];
        }

        $this->db->where( $img_nov->novedad, $id );
        $this->db->delete( $img_nov->name );
        return $to_delete_permantenlty;
    }

}
/* End of Model class */

I want to see the objects in the global scope in the model. I've tried a lot of ways to do this. but there's no way.

This are the error when I access to the model that it's not making sense.

Message: Trying to get property of non-object

P.D.: I don't want alternatives. I know the alternatives and I can make it work in 10 minutes :) I'm just curious about if this can work or not.

  • 写回答

1条回答 默认 最新

  • dongyun9120 2012-12-28 19:59
    关注

    You can't, it's impossible, not even Chuck Norris can access global variables inside a class definition.
    You'll have to pass them to the constructor, or to the method when you need these objects. Think about it: the whole idea behind OOP is to write code once, which can be deployed anywhere, if that code depends on a global variable, called $foo to be defined in the global scope, your code cannot be reused, unless the global scope has the desired objects, with those specific names... If this were allowed, OOP code would be hell to debug: currently, if you get an error saying something is not defined, on line x of a class file, you know that you're trying to access a property. Imagine the horror of having to wade through every line of code, just to find out you wrote: $foo instead of global $foo

    Extra:
    Just thought of a hacky way to sort-of get this to work: assigning the objects to a super-global variable (like $_GLOBALS) will give you access (super-globals can be accessed from within a class). But that's just terrible practice and Very error-prone: every class has access to those objects, and might reassign or change the data, so you have no guarantee that the objects still exist...

    Frankly, if you need access to global variables, you'd better take the time to think about what you actually want to do. For yours, and indeed everybody's sake, you'd better choose, either write everything OO, or nothing. Mixing the two will only cause you grief in the end.

    Since you're using codeigniter, why not take the time to get to know the framework, and use it as it was intended. That way, you avoid reinventing the wheel and, after all: that's what frameworks are for: they offer you a (fairly) well developed backbone that does all the heavy lifting and nitty-gritty stuff so you don't have to.
    Just use the framework and look into the MVC pattern, that's what I'd do...

    Edit:
    The error you're getting makes absolute sense: accessing a property of a non object is to be expected, because you can't use global variables. PHP has this tendency to sort of blunder along, and try to make it all work, so it probably defines a local variable for you, which (as it's not initialized will be assigned NULL), null is not an object, and so you can't access properties. Hence: accessing properties of a non-object.

    Correction
    as @fireeyedboy pointed out to me, it is possible to do this (check comments for link to codepad). I still maintain that this is a terrible way to code, and would even go as far as to call this a bug, that needs to be squashed ASAP.
    If ever I saw a code-equivalent of a cyanide-pill, this is it. Write OO code, that can only work if certain global variables exist is a crime agains humanity!

    评论

报告相同问题?

悬赏问题

  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号