No PHP 4, as variáveis geralmente são declaradas usando var, enquanto no PHP 5 você pode usar os recursos da programação orientada a objetos (OOP) para personalizar a visibilidade dos dados - ou seja, a visibilidade aqui é muito semelhante ao escopo da variável. , mas fornece um mecanismo de controle melhor, existem três tipos de modificadores de visibilidade:
Público (padrão)--As variáveis podem ser acessadas ou modificadas no escopo global.
Protegido - Variáveis só podem ser acessadas ou modificadas dentro da própria classe e classes derivadas diretamente (usando a instrução extends).
Privado – Variáveis só podem ser acessadas ou modificadas dentro da classe.
Assim como as implementações de interface, a violação dessas regras em um programa levará a erros graves e, assim como as interfaces, elas existem apenas para conveniência dos programadores; Mas isso não significa que eles possam ser ignorados. Especificar a visibilidade de uma determinada variável de membro da classe pode proteger os dados dentro do objeto contra influências externas.
Suponha que haja uma classe MySqlDB e uma variável $link seja declarada privada nela, o que significa que esta variável só pode ser acessada de dentro do objeto usando a variável $this. Isso evita a substituição acidental por outros objetos ou funções fora da classe aqui. , usaremos o atributo de visibilidade para nos ajudar a criar um objeto de consulta.
Você pode pensar em uma consulta como uma entidade separada que pode ser executada e retornar resultados. Alguns sistemas de banco de dados também possuem procedimentos armazenados, que são muito semelhantes às funções. Eles armazenam instruções de consulta e aceitam parâmetros correspondentes quando chamados. No entanto, o MySQL não fornecia funções semelhantes antes da versão 5.1, e alguns outros tipos de sistemas de gerenciamento de banco de dados também não.
Neste artigo, os dois recursos acima serão combinados no objeto de consulta do exemplo. O exemplo simulará um procedimento armazenado básico e salvará o ponteiro do resultado internamente. Por enquanto, o foco está na execução da consulta a partir do objeto, onde você pode chamar a função query() do objeto MySqlDB.
As seguintes funções públicas podem ser definidas no objeto de consulta:
__construct()--O construtor aceita um parâmetro que contém uma referência de instância ao objeto que implementa a interface do banco de dados.
prepare()--A função prepare() inicializa o procedimento armazenado de consulta. Pode conter um ou mais espaços reservados limitados, que serão passados como parâmetros para a função execute(). Um espaço reservado é definido como dois pontos relacionados ao número de parâmetros seguidos por um número inteiro e uma letra relacionada ao tipo de parâmetro.
Uma consulta simples contendo espaços reservados se parece com o seguinte:
SELECT col1,col2 FROM table_name WHERE col1=:1I
execute()--A função execute() executará a consulta. Se for inicializado prematuramente como um procedimento armazenado pela função prepare(), quaisquer parâmetros passados serão usados como parâmetros de execução do procedimento armazenado. Caso contrário, o primeiro parâmetro será usado apenas como texto de consulta. A função execute() retornará os resultados após executar a consulta.
compile()--A função compile() é semelhante à função execute(). Na verdade, a consulta não é executada, mas substitui todos os espaços reservados na string de consulta, aceita os parâmetros do procedimento armazenado e retorna a versão compilada. da consulta.
Membros Protegidos
Como mencionado acima, o conceito de visibilidade pode ser usado para ocultar o funcionamento interno de um objeto, protegendo a integridade dos dados necessária para o funcionamento interno. Conforme explicado anteriormente, o ponteiro de resultado retornado pela consulta será salvo como um atributo protegido. O membro protegido é usado aqui porque um objeto de consulta de banco de dados específico derivado do objeto de consulta pode sobrecarregar algumas funções principais.
Chega de
aprofundar a teoria do código
, agora vamos começar a escrever código. Primeiro, crie um modelo conforme mostrado no Exemplo 1:Exemplo 1: Uma
classe de modelo DBQuery
da classe de consulta de banco de dados.
{
/**
*Salve uma referência a um objeto que implementa a interface do banco de dados.
*/
protegido $db;
/**
*Se for um procedimento armazenado, defina como verdadeiro.
*/
protegido $stored_procedure = false
/**
*Salve uma consulta com todas as strings excluídas.
*/
consulta $ privada;
/**
* é usado para combinar aspas no SQL.
*/
privado estático $QUOTE_MATCH = "/(".*(?db = $db;
}
função pública preparar($query)
{
$this->stored_procedure = true;
}
compilação de função pública($args)
{}
função pública executar($query)
{}
}
A função prepare
é o modelo do Exemplo 1. A primeira coisa que você precisa fazer é construir a função prepare(). Para garantir que os caracteres sem aspas sejam analisados acidentalmente como espaços reservados, a função deve remover todos os caracteres da consulta. armazene-os temporariamente em uma matriz. A string em si também será substituída por espaços reservados, que geralmente são reconhecidos como sequências de strings que não devem aparecer na instrução SQL. Durante a compilação da consulta, o espaço reservado do procedimento é primeiro substituído e, em seguida, a string é colocada de volta na consulta. Isso é feito por meio da função preg_replace() e outra função auxiliar de retorno de chamada usada como a função preg_replace().
Exemplo 2: função prepare()
/**
* Prepare a consulta como um procedimento armazenado.
* @param string $query Texto de consulta preparado
* @return nulo
*/
função pública preparar($consulta)
{
$this->stored_procedure = true;
$this->quote_store = array(); //Limpar aspas $this->query = preg_replace(self::$QUOTE_MATCH, '$this->sql_quote_replace("1"?"1":'2')', $ consulta);
}
função privada sql_quote_replace($match)
{
$número = contagem($this->query_strings);
$this->query_strings[] = $match;
retornar "$||$$número";
}
Observe aqui o uso do atributo estático QUOTE_MATCH private, bem como do atributo quote_store e da função sql_quote_replace(). Comparado com protegido, defini-lo como privado aqui garante que qualquer subclasse que substitua o método prepare() da classe de consulta use seu próprio mecanismo para remover aspas.
Compilação de função
A próxima etapa é construir as funções compile() e execute().
A função compile(), conforme mostrado no Exemplo 3, possui as seguintes funções:
·O número de parâmetros aceitos é variável (ou seja, parâmetros variáveis), que corresponderá aos placeholders da consulta.
· Verifique se o placeholder é do tipo de dados correto e substitua-o pelo valor do parâmetro.
·Retorne a consulta como uma string, mas não a execute.
·Se o objeto de consulta não for inicializado como um procedimento armazenado usando a função prepare(), uma exceção será lançada.
Exemplo 3: função compile()
/**
* Retorna a consulta compilada, mas não a executa.
* @param misto $args,... Parâmetros de consulta
* @return string Consulta compilada
*/
compilação de função pública ($params)
{
if (! $this->stored_procedure) {
throw new Exception("O procedimento armazenado não foi inicializado!");
}
/* Parâmetros de substituição*/
$params = func_get_args(); // Obtém os parâmetros da função $query = preg_replace("/(?query);
return $this->add_strings($query); // Coloca a string de volta na consulta
}
/**
* Reinsira a string removida pela função prepare().
*/
função privada add_strings($string)
{
$números = array_keys($this->query_strings);
$contar = contar($números);
$pesquisas = array();
for($x = 0; $x < $contar; $x++) {
$pesquisas[$x] = "$||${$números[$x]}";
}
return str_replace($pesquisas, $this->query_strings, $string);
}
/**
* Cada vez que é executado, um espaço reservado no procedimento armazenado é substituído.
*/
função protegida compile_callback($params, $index, $type)
{
--$index;
/* Lança uma exceção */
if (! isset($params[$index])) {
throw new Exception("O procedimento armazenado não recebeu o número necessário de parâmetros!");
}
/* Você pode adicionar outros tipos aqui, como data e hora. */
switch($tipo){
caso 'S':
retornar '"' . $this->db->escape_string($params[$index]) . '"';
quebrar;
caso 'eu':
return (int) $params[$index];
quebrar;
caso 'N':
retornar (float) $params[$index];
padrão:
throw new Exception("O tipo de dados '$type' especificado no procedimento armazenado não é reconhecido.");
}
}
Duas funções adicionais são usadas na função compile(). A função compile_callback() é usada como uma função de retorno de chamada na chamada da função preg_replace(). Cada vez que um espaço reservado é encontrado na consulta, ele é substituído pelo valor passado para. Ao compilar o valor de uma função, ela será executada.
Função execute
Finalmente, você precisa construir a função execute(). A função execute() compila a consulta e a executa usando o objeto DB, que é usado para inicializar o objeto DBQuery aqui. Observe no Exemplo 4 como a função call_user_func_array() é usada para obter a consulta compilada. A razão para isso é que a função execute() não pode determinar o número de argumentos passados para ela até o tempo de execução.
Exemplo 4: função execute()
/**
*
* Execute a consulta atual e substitua os espaços reservados pelos parâmetros fornecidos.
*
* @param misto $queryParams,... Parâmetro de consulta
* @return resource Uma referência ao recurso que representa a consulta executada.
*/
função pública execute($queryParams = '')
{
//Por exemplo: SELECT * FROM tabela WHERE nome=:1S AND tipo=:2I AND nível=:3N
$args = func_get_args();
if ($this->stored_procedure) {
/* Chama a função compile para obter a consulta */
$query = call_user_func_array(array($this, 'compilar'), $args);
} outro {
/* Se o procedimento armazenado não tiver sido inicializado, execute-o como uma consulta padrão. */
$consulta = $queryParams;
}
$this->resultado = $this->db->query($query);
return $this->resultado;
}
Junte tudo.
Para demonstrar como usar o objeto de consulta, um pequeno exemplo é construído abaixo, que usará o objeto DBQuery como um procedimento armazenado e verificará se o nome de usuário e a senha corretos foram inseridos
. 5:
requer 'mysql_db.php5';
require_once 'query2.php5';
$db = novo MySqlDb;
$db->connect('host', 'nome de usuário', 'pass');
$db->query('use content_management_system');
$query = new DBQuery(
$query->prepare('SELECT fname,sname FROM users WHERE username=:1S AND pword=:2S AND expire_time<:3I ');
if ($resultado = $query->execute("visualad", "avental", time())) {
if ($db->num_rows($resultado) == 1) {
echo('As credenciais estão corretas.');
} outro {
echo('As credenciais estão incorretas e a sessão expirou.');
}
} outro {
echo('Ocorreu um erro ao executar a consulta:' . $db->error());
}
Neste artigo, você viu como proteger dados e limitar a visibilidade de objetos de dados usando os modificadores de acesso private, protected e public ao declarar variáveis de classe. Ao mesmo tempo, no PHP 5, esses conceitos também podem ser usados. outra classe de dados para proteger seus dados internos importantes.