In PHP 4, variables are usually declared using var, while in PHP 5, you can use the features of object-oriented programming (OOP) to customize the visibility of data - that is, accessibility. Visibility here is very similar to variable scope. , but provides a better control mechanism, there are three types of visibility modifiers:
Public (default)--Variables can be accessed or modified in the global scope.
Protected--Variables can only be accessed or modified within the class itself and directly derived (using the extends statement) classes.
Private--Variables can only be accessed or modified within the class.
Like interface implementations, violating these rules in a program will lead to serious errors; and like interfaces, they exist purely for the convenience of programmers. But this does not mean that they can be ignored. Specifying the visibility of a certain class member variable can protect the data within the object from outside influence.
Suppose there is a MySqlDB class and a $link variable is declared private in it, which means that this variable can only be accessed from inside the object using the $this variable. This prevents accidental overwriting by other objects or functions outside the class. Here, we will Use the visibility attribute to help us create a query object.
You can think of a query as a separate entity that can be executed and return results. Some database systems also have stored procedures. Stored procedures are very similar to functions. They store query statements and accept corresponding parameters when called. However, MySQL did not provide similar functions before version 5.1, and some other types of database management systems also No.
In this article, the above two features will be combined into the query object of the example. The example will simulate a basic stored procedure and save the result pointer internally. For now, the focus is on executing the query from the object, where you can call the query() function of the MySqlDB object.
The following public functions can be defined in the query object:
__construct()--The constructor accepts a parameter that contains an instance reference to the object that implements the DB interface.
prepare()--The function prepare() initializes the stored procedure of query. It may contain one or more limited placeholders, which will be passed as parameters to the execute() function. A placeholder is defined as a colon related to the number of parameters followed by an integer and a letter related to the parameter type.
A simple query containing placeholders looks like the following:
SELECT col1,col2 FROM table_name WHERE col1=:1I
execute()--The function execute() will execute the query. If it is prematurely initialized as a stored procedure by the prepare() function, any parameters passed in will be used as execution parameters of the stored procedure. Otherwise, the first parameter will only be used as the query text. The function execute() will return the results after executing the query.
compile()--The function compile() is similar to the function execute(). In fact, the query is not executed, but replaces all placeholders in the query string, accepts the parameters of the stored procedure, and returns the compiled version of the query.
Protected Members
As mentioned above, the concept of visibility can be used to hide the inner workings of an object, protecting the data integrity required for the inner workings. As explained earlier, the result pointer returned by the query will be saved as a protected attribute. The protected member is used here because a specific database query object derived from the query object may overload some core functions.
Enough about
digging into code
theory, now let’s start writing code. First, create a template as shown in Example 1:Example 1: A template
class DBQuery
of the database query class
{
/**
*Save a reference to an object that implements the DB interface.
*/
protected $db;
/**
*If it is a stored procedure, set to true.
*/
protected $stored_procedure = false;
/**
*Save a query with all strings deleted.
*/
private $query;
/**
* is used to match quotes in SQL.
*/
private static $QUOTE_MATCH = "/(".*(?db = $db;
}
public function prepare($query)
{
$this->stored_procedure = true;
}
public function compile($args)
{}
public function execute($query)
{}
}
The prepare function
is the template in Example 1. The first thing you have to do is to construct the prepare() function. To ensure that unquoted characters are accidentally parsed as placeholders, the function should remove all characters in the query. strings and temporarily store them in an array. The string itself will also be replaced by placeholders, which are usually recognized as string sequences that should not appear in the SQL statement. During the compilation of the query, the procedure placeholder is first replaced and then the string is put back into the query. This is done through the preg_replace() function and another helper callback function used as the preg_replace() function.
Example 2: prepare() function
/**
* Prepare the query as a stored procedure.
* @param string $query Prepared query text
* @return void
*/
public function prepare($query)
{
$this->stored_procedure = true;
$this->quote_store = array(); //Clear quotes $this->query = preg_replace(self::$QUOTE_MATCH, '$this->sql_quote_replace("1"?"1":'2')', $ query);
}
private function sql_quote_replace($match)
{
$number = count($this->query_strings);
$this->query_strings[] = $match;
return "$||$$number";
}
Note here the use of the static QUOTE_MATCH attribute private, as well as the quote_store attribute and the sql_quote_replace() function. Compared with protected, defining it as private here ensures that any subclass that overrides the prepare() method of the query class uses its own mechanism to remove quotes.
Function compileThe
next step is to build the compile() and execute() functions.
The function compile(), as shown in Example 3, has the following functions:
·The number of parameters accepted is variable (i.e., variable parameters), which will match the placeholders in the query.
· Check that the placeholder is of the correct data type and replace it with the value in the parameter.
·Return the query as a string but do not execute it.
·If the query object is not initialized as a stored procedure using the prepare() function, an exception will be thrown.
Example 3: compile() function
/**
* Returns the compiled query, but does not execute it.
* @param mixed $args,... Query Parameters
* @return string Compiled Query
*/
public function compile($params)
{
if (! $this->stored_procedure) {
throw new Exception("The stored procedure has not been initialized!");
}
/* Substitution parameters*/
$params = func_get_args(); // Get function parameters $query = preg_replace("/(?query);
return $this->add_strings($query); // Put the string back into query
}
/**
* Reinsert the string removed by the prepare() function.
*/
private function add_strings($string)
{
$numbers = array_keys($this->query_strings);
$count = count($numbers);
$searches = array();
for($x = 0; $x < $count; $x++) {
$searches[$x] = "$||${$numbers[$x]}";
}
return str_replace($searches, $this->query_strings, $string);
}
/**
* Each time it is executed, a placeholder in the stored procedure is replaced.
*/
protected function compile_callback($params, $index, $type)
{
--$index;
/* Throw an exception */
if (! isset($params[$index])) {
throw new Exception("The stored procedure did not receive the required number of parameters!");
}
/* You can add other types here, such as date and time. */
switch ($type) {
case 'S':
return '"' . $this->db->escape_string($params[$index]) . '"';
break;
case 'I':
return (int) $params[$index];
break;
case 'N':
return (float) $params[$index];
default:
throw new Exception("The data type '$type' specified in the stored procedure is not recognized.");
}
}
Two additional functions are used in the function compile(). The compile_callback() function is used as a callback function in the preg_replace() function call. Each time a placeholder is found in the query, it is replaced with the value passed to When compiling the value of a function, it will be executed.
Function execute
Finally, you need to construct the function execute(). The function execute() compiles the query and executes it using the DB object, which is used to initialize the DBQuery object here. Please note in Example 4 how the function call_user_func_array() is used to obtain the compiled query. The reason for this is that the function execute() cannot determine the number of arguments passed to it until runtime.
Example 4: execute() function
/**
*
* Execute the current query and replace the placeholders with the provided parameters.
*
* @param mixed $queryParams,... Query parameter
* @return resource A reference to the resource representing the executed query.
*/
public function execute($queryParams = '')
{
//For example: SELECT * FROM table WHERE name=:1S AND type=:2I AND level=:3N
$args = func_get_args();
if ($this->stored_procedure) {
/* Call function compile to obtain query */
$query = call_user_func_array(array($this, 'compile'), $args);
} else {
/* If the stored procedure has not been initialized, execute it as a standard query. */
$query = $queryParams;
}
$this->result = $this->db->query($query);
return $this->result;
}
Put it all together.
To demonstrate how to use the query object, a small example is constructed below, which will use the DBQuery object as a stored procedure and check whether the correct user name and password are entered. Please see Example 5:
Example 5:
require ' mysql_db.php5';
require_once 'query2.php5';
$db = new MySqlDb;
$db->connect('host', 'username', 'pass');
$db->query('use content_management_system');
$query = new DBQuery($db);
$query->prepare('SELECT fname,sname FROM users WHERE username=:1S AND pword=:2S AND expire_time<:3I ');
if ($result = $query->execute("visualad", "apron", time())) {
if ($db->num_rows($result) == 1) {
echo('The credentials are correct.');
} else {
echo('The credentials are incorrect and the session has expired.');
}
} else {
echo('An error occurred while executing query:' . $db->error());
}
In this article, you have seen how to protect data and limit the visibility of data objects using the access modifiers private, protected, and public when declaring class variables. At the same time, in PHP 5, these concepts can also be used in other Data class to protect its important internal data.