Conexão da base de dados do PHP OOP

Acabei de aprender o conceito de programação orientada a objects e escrevi esta class com funções.

Isso funciona bem, mas estou interessado em saber se eu fiz isso corretamente …

Aqui está o meu código:

class Database{ const DB_HOSTNAME = 'localhost'; const DB_USERNAME = 'root'; const DB_PASSWORD = 'password'; const DB_NAME = 'shop'; protected $_db_connect; protected $_sql; protected $_result; protected $_row; function db_connect(){ $this->_db_connect = mysql_connect(self::DB_HOSTNAME,self::DB_USERNAME,self::DB_PASSWORD) or die(mysql_error()); } function slect_db(){ mysql_select_db(self::DB_NAME) or die(mysql_error()); } function sql(){ $this->_sql = 'SELECT * FROM users'; } function query(){ $this->_result = mysql_query($this->_sql); } function fetch_array(){ while($this->_row = mysql_fetch_array($this->_result)){ $username = $this->_row['user_USERNAME']; echo "
    "; echo "
  • ".$username."
  • "; echo "
"; } } function db_close(){ mysql_close($this->_db_connect); } } $database = new Database(); $database->db_connect(); $database->slect_db(); $database->sql(); $database->query(); $database->fetch_array(); $database->db_close();

Use DOP ou MySQLi, pois é mais seguro e as funções mysql_ * estão obsoletas, conforme descrito acima, forneci algum código genérico usando o PDO para ajudá-lo com esse novo empreendimento. Conforme indicado nos comentários, você realmente não deveria estar ecoando os dados se você estiver procurando por um design orientado a objects, o que você deveria estar fazendo depois de fazer a consulta, retornar as linhas que você buscou e, a partir daí, usar algo como um loop foreach para exibir seus dados. Fazer sua class de database dessa maneira também assegurará que múltiplas conexões de database não estejam abertas de uma só vez! Note, este código é apenas para você fazer referência, e deve ser testado antes de usar na produção ou qualquer coisa ao vivo.

config.php:

  

database.class.php:

 pdo = $pdo; } function getData() { $query = $this->pdo->prepare('SELECT * FROM database'); $query->execute(); return $query->fetchAll(); } } ?> 

index.php:

 getData(); ?> 

A resposta de Sieu Phan está bem, mas na verdade não garante que você tenha apenas uma conexão aberta (você includeá o arquivo config.php várias vezes, criaria várias conexões).

É possível melhorar a forma como você se conecta aos bancos de dados usando contentores de carga automática e de injeção de dependência. Aqui está uma maneira de usar o Auryn para se conectar ao seu database, assegurando-se de que apenas uma conexão esteja aberta e que não precise exigir arquivos manualmente em toda a sua aplicação.

Abrico apenas DO e Auryn aqui. Existem outros recipientes de injeção de dependência e, notavelmente, a extensão mysqli para se conectar ao database, mas o conteúdo deve ajudá-lo a usar outro contêiner, se desejar fazê-lo.

A class de database

Ter uma class de database é supérflua. A class \PDO já está fornecendo todos os methods necessários para consultar o database. Ter uma class de database faz com que você repita todas as funções que ela já fornece e, de fato, limita suas ações (ou faz você criar muitas funções) quando quiser, por exemplo, use vários estilos de busca diferentes, dependendo das suas necessidades em um método específico.

dependency injection

Se você ainda não possui uma injeção de dependência de leitura . O ponto é que, quando uma class precisa acessar o database, não deve ter que se preocupar em construir o object \PDO , ele deve ser construído com ele:

 class Mapper { private $pdo; public function __construct(\PDO $pdo) { $this->pdo = $pdo; } public function createFromId($id) { $stmt = $this->pdo->prepare("SELECT name FROM foo WHERE id=:id"); $stmt->execute([ ":id" => $id, ]); return $stmt->fetchObject(); } } 

Observe que eu passo diretamente o object \PDO , e não uma class wrapper. Dessa forma, eu sempre tenho access a todas as suas capacidades, não apenas um subconjunto de funções definidas pelo usuário.

Container de Injeção de Dependência

Um recipiente de injeção de dependência ajuda a construir suas aulas, dando-lhes os objects que eles precisam e dando-lhe uma grande flexibilidade sobre como realmente criar esses objects. Aqui vou concentrar-me apenas na configuração e compartilhamento de um object \PDO através do uso do Auryn.

Eu suponho que você instalou a class Auryn necessária, a maneira mais fácil é usar o compositor . Isso está fora do escopo desta resposta, existem vários resources sobre como usá-lo.

  • Crie o injetor

     $injector = new \Auryn\Injector(); 
  • Defina os parâmetros da class \PDO

     $injector->define("PDO", [ ":dsn" => "mysql:host=localhost;charset=utf8;dbname=dbname", ":username" => "user", ":passwd" => "passwd", ":options" => [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ], ]); 

    Você pode escrever os parâmetros de configuração diretamente aqui ou obtê-los de um arquivo de configuração. Eu gosto de ter um arquivo config.ini e usar parse_ini_file() para obter minhas opções de configuração, pois posso facilmente mudar de database editando um arquivo de configuração.

  • Compartilhe o object \PDO

     $injector->share("PDO"); 

    Esta parte é realmente importante. Esta linha faz com que o injetor dê o mesmo object \PDO sempre que é encarregado de construir uma class que precise de uma conexão. Observe que a ordem das linhas não é importante, você pode compartilhar a class antes de defini-la, apenas certifique-se de criar seu database que precisa de classs depois de escrever essas duas linhas.

  • Crie seus objects

     $mapper = $injector->make("Mapper"); 

    É isso aí. O injetor criará seu object mapeador, criando o object \PDO se ainda não estiver, passando a instância existente se tiver.

Autoloading

Supondo que você tenha usado o compositor, você pode fazer uso de um autoloader ótimo. Caso contrário, você também pode rolar seu próprio carregador automático .

O ponto aqui é parar de require() em todo o seu código, especialmente se você tiver hierarquias de class complexas, o que você deve ter em um único sistema de class compatível com responsabilidade .

Empacotando

Com esta configuração, agora você pode usar o object \PDO em suas aulas enquanto estiver certo de que só haverá uma instância por solicitação, sem a necessidade de exigir arquivos em todos os lugares e sem usar um anti-padrão singleton.

 $database = new Connection(); class Connection { function __construct() { switch($_SERVER['DOCUMENT_ROOT']) { case 'path': $this->host = 'hostname'; $this->user = 'username'; $this->passwd = 'password'; $this->database = 'dbname'; break; default : $this->host = 'localhost'; $this->user = 'root'; $this->passwd = 'root'; $this->database = 'dbname'; break; } $this->clink = @mysql_connect($this->host,$this->user,$this->passwd); @mysql_select_db($this->database,$this->clink); } } 

$ objConn = new mysqlconnect (); $ Conn = $ objConn-> setobjConnect (“localhost”, “root”, “P @ ssw0rd”);

 class Database{ var $last_query; //Saved result of the last query made var $last_result; //Results of the last query made var $func_call; //A textual description of the last query/get_row/get_var call var $link; //database link var $lastquery; //last query var $result; //query result // Connect to MySQL database function database() { $this->link=mysql_connect(DB_HOST, DB_USER, DB_PASS) or die('Server connexion not possible.'); //Set All Charsets to UTF8 mysql_query("SET character_set_results=utf8 , character_set_client=utf8 , character_set_connection=utf8 , character_set_database=utf8 , character_set_server=utf8"); mysql_select_db(DB_NAME) or die('Database connection not possible.'); } /** Query the database. * @param $query The query. * @return The result of the query into $lastquery, to use with fetchNextObject(). */ function query( $query ){ $this->lastquery=$query; $this->result=@mysql_query( $query, $this->link ); return $this->result; } /** Do the same as query() but do not return nor store result. * Should be used for INSERT, UPDATE, DELETE... * @param $query The query. * @param $debug If true, it output the query and the resulting table. */ function execute($query) { @mysql_query($query); } /** Convenient method for mysql_fetch_object(). * @param $result The ressource returned by query(). * @return An ARRAY representing a data row. */ function fetchArray($result){ if ($result == NULL) $result = $this->result; if ($result == NULL || mysql_num_rows($result) < 1) return NULL; else return mysql_fetch_assoc($result); } /** Close the connecion with the database server. * It's usually unneeded since PHP do it automatically at script end. */ function close() { mysql_close($this->link); } /** Get the number of rows of a query. * @param $result The ressource returned by query(). If NULL, the last result returned by query() will be used. * @return The number of rows of the query (0 or more). */ function numRows($result = NULL) { if ($result == NULL) return @mysql_num_rows($this->result); else return mysql_num_rows($result); } } 
 ![server = $s; $this->user = $u; $this->password = $p; return $this->objConnect = mysql_connect($this->server,$this->user,$this->password); } } $objConn = new mysqlconnect(); $Conn = $objConn->setobjConnect("localhost","root","P@ssw0rd"); if($Conn) { echo "Database Connect"; } else { echo "Database Connect Failed."; } mysql_close($Conn); ?>] 

1