sql >> Databáze >  >> RDS >> Mysql

PHP Ukládání relací do databáze. Zdá se, že metoda čtení nefunguje

Používáte Codeigniter. Má funkci ukládání relací do již vestavěné databáze.

Jednoduše odstraňte svůj kód, který nefunguje, a místo toho použijte funkci Codeigniter. Stačí jej pouze nakonfigurovat.

Kromě toho, pokud opravdu chcete „zůstat se svými“, existuje několik problémy s vaším kódem. Jsou snadno rozpoznatelné, pokud budete postupovat podle následujících bodů:

  1. Přečtěte si o každé funkci zpětného volání pro obslužnou rutinu uložení relace. Zejména to, která data přijímají a v jakém formátu (nečiní-li tak, vede to minimálně k jedné chybě, která je schopna vyvolat chování, které popisujete jako „nefungující“).
  2. Proveďte protokolování chyb. Problém s obslužnou rutinou ukládání, který vede k chybám, je může nechat neviditelné, protože výstup do prohlížeče již není možný. To vyžaduje protokolování chyb do souboru. To je velmi důležité při odstraňování problémů s obslužným programem pro uložení relace.
  3. Přesuňte kód interakce s databází z cesty. To vám také umožňuje poskytovat lepší informace o chybách v případě selhání interakce s databází (pokud tak neučiníte, skryje se alespoň jedna chyba, která může vést k chování, které popisujete jako „nefunkční“).
  4. Odstraňte nepotřebný kód. Chci říct, není to potřeba. Kód, který není potřeba, může obsahovat chyby, které vedou ke scénáři „nefunguje“, který zde máte. Takže si bráníte dělat věci bez důvodu. Jeden příklad:ini_set("session.save_handler", "user"); - Dokud nemáte ponětí, co děláte, nedělejte to. Neexistuje žádný předdefinovaný savehandler s názvem user v PHP, ani to nedefinujete.

A to je v podstatě vše. Mohl jsem tedy zaznamenat dvě skutečné chyby, které to způsobují, ostatní kroky jsou nezbytné, abyste se mohli vypořádat s budoucími problémy:

  1. Ujistěte se, že se vždy vztahujete ke stejné databázové tabulce. Pokud například zapíšete do tabulky MY_SESSIONS a číst z tabulky SESSIONS , to nikdy nebude fungovat.
  2. Ujistěte se, že data, která poskytujete PHP, jsou kompatibilní s daty, která očekává. Pokud například uložíte data zakódovaná v Base64 do databáze a vrátíte je zpět do PHP zakódovaná v Base64, PHP s těmito daty nemůže nic dělat.

Další potenciální problémy, které nejsou viditelné z vašeho kódu:

  1. Schéma databáze, které máte, se nehodí pro data, která v něm ukládáte (neposkytli jste schéma tabulky, takže nelze říci, zda vám to způsobuje problémy, či nikoli).
  2. Identifikátor odkazu na databázi se může změnit, protože samotný codeigniter vytváří připojení k databázi. To by mohlo vést k potenciálním vedlejším účinkům. Explicitní uvedení identifikátoru odkazu pro připojení k databázi pomáhá ke klidnému spánku.
  3. Chyby v dotazech SQL, které zůstaly bez povšimnutí, protože chybí zpracování chyb pro části databáze.

Příklad kódu:

ob_start();

session_name("test");
session_set_cookie_params(0, '/', '.test.com');

$s = new SessionManagement();
$s->register();

session_start();

ECHO $_SESSION['test'], "\n"; # value

Refactored SessionManagement třída:

class SessionManagement
{
    private $_timeout;
    private $_db;

    public function __construct() {

        $CI =& get_instance();
        $CI->load->database();

        $this->_db = new LegacyMysqlDatabase(
            $CI->db->hostname, $CI->db->username, $CI->db->password, $CI->db->database
        );

        $this->_timeout = 60 * 60 * 10;
    }

    public function _open() {

        return TRUE;
    }

    public function _close() {

        return TRUE;
    }

    public function _read($session_id) {

        $db         = $this->_db;
        $session_id = $db->escape($session_id);
        $sql        = "SELECT session_data
            FROM   SESSION
            WHERE  session_id = '$session_id'";

        if (!($result = $db->query($sql)) || !$result->getNumberOfRows()) {
            return '';
        }

        $record = $result->fetchAssoc();
        return $record['session_data'];
    }

    public function _write($session_id, $session_data) {

        $db              = $this->_db;
        $session_id      = $db->escape($session_id);
        $session_data    = $db->escape($session_data);
        $session_expires = time() + $this->_timeout;

        $sql = "REPLACE INTO SESSION (session_id,    session_data,    session_expires)
                             VALUES  ('$session_id', '$session_data', $session_expires)";

        return (bool)$db->query($sql); // cast to bool because PHP would cast to int
    }

    public function _gc($max) {

        return TRUE;
    }

    public function _destroy($id) {

        $db         = $this->_db;
        $session_id = $db->escape($id);
        $sql        = "DELETE
                FROM   SESSION
                WHERE  session_id = '$id'";

        return $db->query($sql);
    }

    public function register() {

        $registered = session_set_save_handler(
            array($this, '_open'),
            array($this, '_close'),
            array($this, '_read'),
            array($this, '_write'),
            array($this, '_destroy'),
            array($this, '_gc')
        );
        if (!$registered) {
            throw new Exception('Can not register session savehandler.');
        }
    }
}

Kód interakce s databází se zpracováním chyb:

class LegacyMysqlDatabase
{
    private $_hostname;
    private $_username;
    private $_password;
    private $_database;

    private $_link;
    private $_initError = false;

    public function __construct($hostname, $username, $password, $database) {

        $this->_hostname = $hostname;
        $this->_username = $username;
        $this->_password = $password;
        $this->_database = $database;
    }

    public function query($sql) {

        $link   = $this->getLink();
        $result = mysql_query($sql, $link);
        if ($result === false) {
            trigger_error(sprintf('Query "%s" failed: #%d: %s', $sql, mysql_errno($link), mysql_error($link)));
            throw new Exception('Failed to query Mysql database.');
        }
        return new LegacyMysqlResult($result);
    }

    public function escape($string) {

        return mysql_real_escape_string($string, $this->getLink());
    }

    private function getLink() {

        if ($this->_initError) {
            throw new Exception('Failed to initialize the database.');
        }

        if ($this->_link === null) {
            $this->_initError = true;
            $result           = mysql_connect($this->_hostname, $this->_username, $this->_password);
            if (!$result) {
                throw new Exception('Can not connect to Mysql database.');
            }
            $this->_link = $result;
            $selected    = mysql_select_db($this->_database, $this->_link);
            if (!$selected) {
                trigger_error(sprintf('Can not select Mysql database "%s": #%d: %s', $this->_database, mysql_errno($result), mysql_error($result)));
                throw new Exception(sprintf('Can not select Mysql database "%"', $this->_database));
            }
            $this->_initError = false;
        }
        return $this->_link;
    }
}

class LegacyMysqlResult
{

    private $_result;

    public function __construct($result) {

        $this->_result = $result;
    }

    public function getNumberOfRows() {

        return mysql_num_rows($this->_result);
    }

    public function fetchAssoc() {

        return mysql_fetch_assoc($this->_result);
    }
}


  1. použijte proměnnou php v názvu tabulky vytvoření mysql

  2. Jak opravit „Možnost konfigurace ‚Agent XPs‘ neexistuje“ v SQL Server (T-SQL)

  3. Oracle Převod sekund na hodiny:minuty:sekundy

  4. Jak mohu (nebo mohu) SELECT DISTINCT na více sloupcích?