Por que PHP e PostgreSQL são amor à primeira consulta?
\n\nO mundo do desenvolvimento web está cheio de estereótipos. Um deles diz: "PHP só é amigo do MySQL". Há alguma verdade nisso, mas apenas até você experimentar a combinação PHP e PostgreSQL. É como passar de uma bicicleta para uma moto esportiva: as mesmas rodas, mas a velocidade, manobrabilidade e confiabilidade são completamente diferentes.
\n\nPostgreSQL não é apenas um banco de dados. É um monstro objeto-relacional que sabe trabalhar com JSON, dados geoespaciais, busca em texto completo e transações complexas. E o PHP é o maestro ideal para esta orquestra. Neste guia, abordaremos tudo: desde a instalação do driver até a escrita de código pronto para produção. Vamos nessa!
\n\n1. Instalação e configuração: preparando as ferramentas
\n\nAntes de escrever código, vamos garantir que o PHP saiba da existência do PostgreSQL. Na maioria das distribuições modernas do PHP (por exemplo, XAMPP, OpenServer, Docker), a extensão pdo_pgsql já existe, mas precisa ser ativada.
1.1. Ativando a extensão no php.ini
\n\nAbra seu php.ini e descomente (remova o ponto e vírgula no início) a linha:
extension=pdo_pgsql\n\nSe você usa Linux, a instalação é assim:
\n\nsudo apt-get install php-pgsql\nsudo service apache2 restart # ou nginx + php-fpm\n\n1.2. Criando banco e usuário
\n\nAcesse o console do PostgreSQL:
\n\nsudo -u postgres psql\n\nAgora vamos criar um banco de dados e um usuário para nosso projeto:
\n\nCREATE DATABASE pythonlib_blog;\nCREATE USER myapp WITH PASSWORD 'SuperSecret123';\nGRANT ALL PRIVILEGES ON DATABASE pythonlib_blog TO myapp;\n\\q\n\nPronto. Agora temos um banco pythonlib_blog e um usuário myapp.
2. Primeira conexão: PDO como padrão
\n\nNunca use as funções antigas pg_connect(). No PHP moderno existe o PDO (PHP Data Objects) — uma interface única para trabalhar com diferentes bancos de dados. É mais seguro, mais conveniente e suporta consultas preparadas.
2.1. Classe wrapper para conexão
\n\nVamos criar uma classe simples Database que gerenciará a conexão:
<?php\n\nclass Database {\n private static ?PDO $instance = null;\n private const DB_HOST = 'localhost';\n private const DB_PORT = 5432;\n private const DB_NAME = 'pythonlib_blog';\n private const DB_USER = 'myapp';\n private const DB_PASS = 'SuperSecret123';\n\n public static function getConnection(): PDO {\n if (self::$instance === null) {\n $dsn = "pgsql:host=" . self::DB_HOST . ";port=" . self::DB_PORT . ";dbname=" . self::DB_NAME;\n try {\n self::$instance = new PDO($dsn, self::DB_USER, self::DB_PASS, [\n PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,\n PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,\n PDO::ATTR_EMULATE_PREPARES => false,\n ]);\n } catch (PDOException $e) {\n die("Connection failed: " . $e->getMessage());\n }\n }\n return self::$instance;\n }\n}\n\nPor que isso é legal? Primeiro, singleton — não criamos uma nova conexão a cada requisição. Segundo, ATTR_EMULATE_PREPARES => false força o PostgreSQL a usar consultas preparadas reais, em vez de emulação no lado do PHP. Isso melhora o desempenho e a segurança.
3. Operações CRUD: criar, ler, atualizar, deletar
\n\nAgora a parte principal. Suponha que temos uma tabela articles para artigos no pythonlib.ru.
3.1. Criando a tabela
\n\nExecute este SQL no seu banco de dados (via psql ou painel de administração):
\n\nCREATE TABLE articles (\n id SERIAL PRIMARY KEY,\n title VARCHAR(255)