类中的MySQL导致沮丧

时间:2012-08-09 18:54:38

标签: php mysql global-variables

我有这段代码:

<?php 

class guildData {

    public $email = NULL;
    public $hash_pw = NULL;
    public $user_id = NULL;
    public $clean_username = NULL;
    public $display_username = NULL;

    public function selectGuild($g_id)
    {
            global $db,$db_table_prefix;

            $this->g_id = $g_id;

            $sql = "SELECT
                            name
                            FROM
                            guild
                            WHERE
                            id = '".$g_id."'";

            $result = $db->sql_query($sql);

            $row = $db->sql_fetchrow($result);

            return ($row['name']);
    }
}
?>
<?php echo $guildData->selectGuild(1); ?>

我只是得到500错误,IDEone也给了我这个:

致命错误:在第32行的/home/VT00Ds/prog.php中调用非对象的成员函数selectGuild()

我看不出错误,你能帮助我吗?

2 个答案:

答案 0 :(得分:4)

你做错了。

  1. 摆脱全局变量。相反,如果类需要DB访问,那么您应该将它注入构造函数中:

    class GuildData
    {
        //  ... snip 
    
        protected $connection;
    
        public function __construct( PDO $connection )
        {
            $this->connection = $connection;
        }
    
        //  ... snip 
    }
    
  2. 您的代码有可能进行SQL注入。您应该使用预准备语句,而不是连接查询:

    $statement = $this->connection->prepare(
                    'SELECT name FROM guild WHERE id = :id'
                 );
    $statement->bindParam( ':id', $this->g_id, PDO::PARAM_INT );
    if ( $statement->execute() )
    {
        $data = $statement->fetch( PDO::FETCH_ASSOC );
    }
    
  3. 您必须先实例化对象,然后才能使用它们:

    $pdo = new PDO('mysql:host=localhost;dbname=myMagicalDB;charset=UTF-8', 
                   'username', 'password');
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $guild = new GuildData( $pdo );
    $guild->selectGuild(42);
    
  4. 您可以考虑从域逻辑中分离出与DB交易的部分。基本上让其他类处理提取和存储数据,而Guild类管理逻辑。您可能会发现thisthis回答相关。

  5. 请勿使用public个变量。您通过直接公开内部数据来打破对象的封装。相反,您应将其定义为protectedprivate

    你也可能会仔细研究你实际保留的内容。为什么GuildData需要$hash_pw$clean_username

答案 1 :(得分:3)

您尚未实例化$guildData。如果要在不实例化对象的情况下使用此方法,则该方法应为static

class guildData {
    public static function selectGuild($g_id) { ... }
}

然后你可以从

调用它
echo guildData::selectGuild(1);

否则,您需要实例化一个对象

$guildData = new GuildData();

echo $guildData->selectGuild(1);

此外,您应该在其中使用某种__construct()方法,以便设置成员变量。

更新我还注意到您的selectGuild()方法出错:

$this->g_id = $g_id;

设置g_id的值,该值未在类中定义为成员变量。您必须在类定义中将g_id声明为成员变量:

class guildData {
    public $email = NULL;
    public $hash_pw = NULL;
    public $user_id = NULL;
    public $clean_username = NULL;
    public $display_username = NULL;

    public $g_id = NULL;

    .
    .
    .

}

最后,sql_query()不是我听过的PHP方法。除非您使用的是定义这些方法的库,否则我认为您的意思是mysql_query()。如果是这种情况,则应停止使用mysql_*函数。他们被弃用了。而是使用PDO(从PHP 5.1开始支持)或mysqli(从PHP 4.1开始支持)。如果您不确定使用哪一个,read this SO article