FastSitePHP\Data\Database

The Database class provides a thin wrapper for PHP Data Objects to reduce the amount of code needed when querying a database.

Código Fonte

GitHub

Código de Exemplo

Conecte a um Banco de Dados e rode Consultas SQL

// O FastSitePHP fornece um classe Database que é uma fina camada que
// envolve o PDO, reduzindo a quantidade de código necessária ao consultar
// um banco de dados. Um exemplo adicional nesta página, mostra como
// utilizar PDO.

// Conecte a um Bando de Dados. Este exemplo utiliza SQLite com um bd
// temporário na memória.
$dsn = 'sqlite::memory:';
$db = new \FastSitePHP\Data\Database($dsn);

// Dependendo da conexão, quatro parâmetros adicionais podem também serem
// utilizados:
/*
$user = null;
$password = null;
$persistent = false;
$options = [];
$db = new Database($dsn, $user, $password, $persistent, $options);
*/

// Cria tabelas e registros de teste. A função [execute()] é utilizada para
// consulta de ação (INSERT, UPDATE, DELETE, CREATE etc) e retorna o número
// de linhas afetadas.

$db->execute('CREATE TABLE page_types (id INTEGER PRIMARY KEY, page_type)');

$sql = 'CREATE TABLE pages (id INTEGER PRIMARY KEY AUTOINCREMENT,';
$sql .= ' type_id, title, content)';
$db->execute($sql);

// Este exemplo utiliza áspas duplas para a string ["] por que strings SQL
// incluem o caractere áspas simples ['] para texto.
$sql = "INSERT INTO page_types (id, page_type) VALUES (1, 'text/plain')";
$rows_added = $db->execute($sql);

// Um segundo parâmetro opcional pode ser utilizado. Isto é recomendado
// para prevenir ataques de SQL Injection via entradas de usuário. O ponto
// de interrogação [?] é um caractere que representa um espaço reservado
// a ser utilizado pela expressão SQL.
$sql = 'INSERT INTO page_types (id, page_type) VALUES (?, ?)';
$params = [2, 'text/html'];
$rows_added += $db->execute($sql, $params);

// Múltiplos registros pode ser adicionados (ou atualizados etc) ao
// utilizar [executeMany()]
$sql = 'INSERT INTO pages (type_id, title, content) VALUES (?, ?, ?)';
$records = [
    [1, 'Página de Teste em Texto', 'Isto é um teste.'],
    [2, 'Página de Teste em HTML', '<h1>Teste<h1><p>Isto é um teste.</p>'],
];
$rows_added += $db->executeMany($sql, $records);

// Além de utilizar [?], você também pode utilizar parâmetros nomeados no
// formato ":name". Parâmetros nomeados pode fazer com que o código seja
// mais fácil de ler.
$sql = 'INSERT INTO pages (type_id, title, content)';
$sql .= ' VALUES (:type_id, :title, :content)';
$params = [
    'type_id' => 1,
    'title'   => 'Parâmetros Nomeados',
    'content' => 'Teste com Parâmetros Nomeados.',
];
$rows_added += $db->execute($sql, $params);

// Obtenha a ID da última linha ou valor sequencial inserido
$last_id = $db->lastInsertId();

// Consulte Múltiplos Registros
// Retorna um Array de Registros (Array Associativo para cada Registro).
$sql = 'SELECT * FROM pages';
$records = $db->query($sql);

// Consulta um registro. Retorna um Array Associativo ou [null] se não
// encontrado. Ambas [query()] e [queryOne()] suportam parâmetros opcionais
// ao consultar.
$sql = 'SELECT * FROM pages WHERE id = ?';
$params = [1];
$record = $db->queryOne($sql, $params);

// A classe [Database] também contém funções adicionais tal como
// [queryValue(), queryList() e querySets()] para simplificar e reduzir a
// quantidade de código necessária ao trabalhar com bancos de dados.

COnectar a um Banco de Dados

// A classe Database do FastSitePHP ou a classe PHP integrada PDO,
// pode conectar a bancos de dados diferentes. A classe Database do
// FastSitePHP fornece um classe Database que é uma fina camada que
// envolve o PDO, reduzindo a quantidade de código necessária ao consultar
// um banco de dados.

// O exemplos abaixo mostram coo construir strings de conexão e rodar
// uma query para um número diferente bancos de dados. Se você baixar
// este site, o código abaixo pode ser modificado e testado para seu
// ambiente; or simplesmente copie o que você precisa para seu site
// ou app.

// Ao especificar o hostname (Nome do Server), muitas vezes você pode
// somente especificar o nome do servidor (exemplo: 'db-server') ou
// o nome de domínio totalmente qualificado (FQDN) (example
// 'db-server.example.com') baseado-se em como sua rede é configurada.
// Por exemplo em uma rede interna, simplesmente utilizando o nome
// de servidor funcionará, mas através de uma VPN é geralmente
// necessário utilizar o FDQN.

// ----------------------------------------------------------------------------
// MySQL
//   Format Básico:
//     "mysql:host={hostname};dbname={database}";
//
// Este exemplo também mostra o uso da opção [MYSQL_ATTR_INIT_COMMAND]
// para definir o fuso horário para UTC quando a conexão é criada.
//
// Se você tem um site ou aplicação que tem usuários em múltiplos
// fuso horários ou países, um modelo de aplicação que funciona bem
// é o de salvar todas as datas e horários em UTC e daí formatar
// baseando-se no fuso horário selecionado pelo usuário.
//
$dsn = 'mysql:host=localhost;dbname=wordpress;charset=utf8';
$user = 'root';
$password = 'wordpress';
$options = [
    \PDO::MYSQL_ATTR_INIT_COMMAND => "SET time_zone = '+00:00'",
];
$sql = 'SELECT table_schema, table_name';
$sql .= ' FROM information_schema.tables';
$sql .= " WHERE table_type = 'BASE TABLE'";

// ----------------------------------------------------------------------------
// Oracle
//   Formato:
//      "oci:dbname=//{hostname}:{port-number}/{database}"
$dsn = 'oci:dbname=//server:1521/hr';
$user = 'sys';
$password = 'password';
$options = [];
$sql = 'SELECT OWNER, TABLE_NAME FROM ALL_TABLES ORDER BY OWNER, TABLE_NAME';

// Além do formato padrão, você pode também especificar uma string TNS
// completa
$tns = '(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)';
$tns .= '(HOST=server.example.com)(PORT=1521)))';
$tns .= '(CONNECT_DATA=(SERVICE_NAME=dbname)))';
$dsn = 'oci:dbname=' . $tns;

// ----------------------------------------------------------------------------
// SQL Server
$dsn = 'sqlsrv:Server=db-server;Database=DbName';
$user = 'sa';
$password = 'password';
$options = [];
$sql = 'SELECT SCHEMA_NAME(schema_id) AS schema_name, name FROM sys.tables';

// SQL Server (utilizando ODBC)
// Se o driver PDO nativo de SQL Server não estiver instalado e o
// Driver PDO para ODBC estiver e a Conexão ODBC estiver definida,
// você poderia utilizar isso:
$dsn = 'odbc:DRIVER={SQL Server};SERVER=db-server;DATABASE=DbName;';

// ----------------------------------------------------------------------------
// IBM (utilizando ODBC)
// Este exemplo mostra uma conexão a um IBM DB2 ou AS/400 através do
// iSeries.
// Opções ODBC variarão com base no driver instalado ou utilizado.
$dsn = 'odbc:DRIVER={iSeries Access ODBC Driver};';
$dsn .= 'HOSTNAME=AS400.EXAMPLE.COM;';
$dsn .= 'PORT=56789;';
$dsn .= 'SYSTEM=SYSTEM;';
$dsn .= 'PROTOCOL=TCPIP;';
$dsn .= 'UID=USER;';
$dsn .= 'PWD=PASSWORD;';
$user = null;
$password = null;
$options = [];
$sql = 'SELECT SYSTEM_TABLE_SCHEMA, TABLE_NAME, TABLE_TEXT';
$sql .= ' FROM QSYS2.SYSTABLES';
$sql .= " WHERE SYSTEM_TABLE_SCHEMA IN 'QSYS'";
$sql .= ' ORDER BY SYSTEM_TABLE_SCHEMA, TABLE_NAME';
$sql .= ' FETCH FIRST 100 ROWS ONLY';

// ----------------------------------------------------------------------------
// PostgreSQL
$dsn = 'pgsql:host=localhost;port=5432;dbname=dbname;';
$user = 'postgres';
$password = 'password';
$options = [];
$sql = 'SELECT table_schema, table_name';
$sql .= ' FROM information_schema.tables';
$sql .= " WHERE table_type = 'BASE TABLE'";

// ----------------------------------------------------------------------------
// SQLite
//   Exemplo utilizando um caminho de arquivo:
//     'sqlite:/var/www/app_data/db.sqlite'
//     'sqlite:C:\inetpub\wwwroot\db.sqlite'
//   Banco de Dados em Memória:
//     'sqlite::memory:'
$dsn = 'sqlite:' . $file_path;
$user = null;
$password = null;
$options = [];
$sql = 'SELECT * FROM sqlite_master';

// ----------------------------------------------------------------------------
// Opção e Conexão Persistente
//
// Muitos drivers de Bancos de Dados PHP suportam conexões persistentes
// o que permite um melhor desempenho.
$persistent = false;

// ============================================================================
// Conecte utilizando PHP Data Objects (PDO)
$options[\PDO::ATTR_ERRMODE] = \PDO::ERRMODE_EXCEPTION;
if ($persistent) {
    $options[\PDO::ATTR_PERSISTENT] = true;
}
$pdo = new \PDO($dsn, $user, $password, $options);

// Consulte utilizando PDO
$stmt = $pdo->query($sql);
$records = $stmt->fetchAll(\PDO::FETCH_ASSOC);

// =================================================================================
// Conecte e Consulte utilizando a classe Database do FastSitePHP.
// Somente o DSN (Data Source Name/Nome da Fonte de Dados) é um parâmetro necessário.
$db = new \FastSitePHP\Data\Database($dsn, $user, $password, $persistent, $options);
$records = $db->query($sql);

// =================================================================================
// Além da classe Database do FastSitePHP, [OdbcDatabase] e [Db2Database] também
// podem ser utilizadas para suportar ambientes, e especialmente Bancos de Dados IBM.
//
// Ao utilizar a classe [OdbcDatabase] o DSN será o mesmo que o do PDO excluindo
// o prefixo 'odbc:'.
/*
$odbc = new OdbcDatabase($dsn, $user, $password, $persistent, $options);
$db2  = new Db2Database($dsn, $user, $password, $persistent, $options);
*/

// ============================================================================
// Lazy Loading com FastSitePHP
//
// O objeto Application do FastSitePHP tem uma função [lazyLoad()] que aceita
// um nome de propriedade e função callback. Isso cria o objeto como uma
// propriedade da app somente se utilizada. Isto é ideal para trabalhar com
// sites onde algumas páginas conectam a um banco de dados e algumas não, ou
// se você tem um site que conecta-se à múltiplos bacos de dados mas nem todas
// as páginas utilizam à cada um.
$app->lazyLoad('db', function() use ($dsn, $user, $password) {
    return new \FastSitePHP\Data\Database($dsn, $user, $password);
});

// Consulta para registros. O banco de dados é conectado aqui somente quando usado pela primeira vez.
$records = $app->db->query($sql);

// ============================================================================
// Para obter uma lista dos drivers disponíveis no computador chame
// [phpinfo()] e veja o resultado ou chame a seguinte função para obter uma
// array de nomes de drivers. Uma lista completa de drivers PDO pode ser
// encontrada em:
//   http://php.net/manual/en/pdo.drivers.php
// Se você precisar de um driver que não estiver disponível ou ativado em
// seu servidor, eles geralmente são fáceis de serem instalados e ativados.
$drivers = \PDO::getAvailableDrivers();

Propriedades

Nome Tipo de Dados Padrão Descrição
db null
PDO
null PDO Object for the Database

Métodos

__construct($dsn, $user = null, $password = null, $persistent = false, array $options = array())

Class constructor. Creates Db Connection using PDO.

query($sql, array $params = null)

Run a Query and return results as any array of records. Records are each associative arrays. If no records are found an empty array is returned.

Retorna: array

queryOne($sql, array $params = null)

Query for a single record and return it as a associative array or return null if the record does not exist.

Retorna: array | null

queryValue($sql, array $params = null)

Query for a single value from the first column of the first record found. If no records were found null is returned.

Retorna: mixed

queryList($sql, array $params = null)

Query for an array of values from the first column of all records found.

Retorna: array

querySets($sql, array $params = null)

Query for and return multiple Row Sets from a single query. This feature works in most databases but is not available for SQLite.

Retorna: array

execute($sql, array $params = null)

Run a SQL Action Statement (INSERT, UPDATE, DELETE, etc) and return the number or rows affected. If multiple statments are passed then the returned row count will likely be for only the last query.

Retorna: int - Row count of the last query

lastInsertId($name = null)

Returns the ID of the last inserted row or sequence value. This calls the PDO function [lastInsertId()]. Additionally if using SQL the last ID can be obtained from the following queries:

    MySQL:      SELECT LAST_INSERT_ID()
    SQLite:     SELECT last_insert_rowid()
    SQL Server: SELECT SCOPE_IDENTITY()
                SELECT @@IDENTITY
    IBM:        SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1

Oracle and PostgreSQL uses Sequence Objects of Auto-Numbers.

Example if using SQL with [queryValue()]:
    $id = $db->queryValue('SELECT SCOPE_IDENTITY()');

Retorna: string

executeMany($sql, array $records)

Prepare a SQL Statement and run many record parameters against it. This can be used for transacations such as bulk record inserts. Returns the total number of rows affected for all queries.

Retorna: int

trimStrings($new_value = null)

Propriedade Getter / Setter

Get or set whether spaces on strings should be trimmed when calling [query(), queryOne(), queryValue(), queryList(), querySets()].

When called strings are trimmed after the records are queried and before the function returns the result.

Often legacy databases will use [CHAR] text fields over [VARCHAR] or similar types. For example when using a [CHAR] field:
    Field: [name] CHAR(20)
    Data saved as "John                "

When querying by default the spaces will be returned however if this function is set to [true] then "John" would be returned.

Defaults to [false]. Calling this function takes extra memory vs not using it so if you have a high traffic site and want to trim strings you may want to do so in the SQL Statement and keep this [false].

For a small amount of records (several hundred or less) this has little or not noticeable impact however if using a large set of records (1,000+) this setting may cause a about a 10% increase in memory or more.

Retorna: bool | $this