0

我有这个代码:

<?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()

我看不到错误,你能帮帮我吗?

4

2 回答 2

4

You are doing it wrong.

  1. Get rid of the global variables. Instead , if the class needs DB access , then you should inject it in the constructor:

    class GuildData
    {
        //  ... snip 
    
        protected $connection;
    
        public function __construct( PDO $connection )
        {
            $this->connection = $connection;
        }
    
        //  ... snip 
    }
    
  2. Your code has potential for SQL injections. Instead of concatenating the query, you should use prepared statements:

    $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. You have to instantiate object, before you can use them:

    $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. You might consider separating the part with deals with DB from the domain logic. Essentially letting some other class to handle the fetching and storing the data, while the Guild class manages the logic. You might find this and this answer relevant.

  5. Do not use public variables. You are breaking the encapsulation of the object by directly exposing the internal data. Instead you should define them as protected or private.

    You might also take a hard look at what you are actually keeping there. Why does GuildData need $hash_pw or $clean_username ?

于 2012-08-09T19:13:32.950 回答
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;

Sets the value of g_id, which is not defined as a member variable in the class. You must declare g_id as a member variable in your class definition:

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;

    .
    .
    .

}

Finally, sql_query() is not a PHP method that I've ever heard of. Unless you're using a library that defines these methods, I think you mean mysql_query(). If this is the case, you should stop using mysql_* functions. They're being deprecated. Instead use PDO (supported as of PHP 5.1) or mysqli (supported as of PHP 4.1). If you're not sure which one to use, read this SO article.

于 2012-08-09T18:56:21.820 回答