search
HomeBackend DevelopmentPHP Tutorial10 Advanced PHP Tips [Revised Edition]_PHP Tutorial

10 Advanced PHP Tips [Revised Edition]_PHP Tutorial

Jul 21, 2016 pm 03:25 PM
phpsqlusein principleBasicSkillGenuineuserofadvanced

1. Use a SQL Injection Cheat Sheet
A basic principle is to never trust user-submitted data.
Another rule is to escape data when you send or store it.
can be summarized as: filter input, escape output (FIEO). Input filtering, output escape.
The usual cause of SQL injection vulnerabilities is that the input is not filtered, as in the following statement:

Copy code The code is as follows:

$query = "SELECT *
FROM users
WHERE name = '{$_GET['name']}'";

In this In the example, $_GET['name'] comes from user-submitted data, which is neither escaped nor filtered~~
For escaped output, you have to remember that data used outside your program needs to be escaped meaning, otherwise, it may be parsed incorrectly.
In contrast, filtering input ensures that the data is correct before use.
With filtered input, you have to remember that raw data outside your program needs to be filtered because it cannot be trusted.
The following example demonstrates input filtering and output escaping:
Copy the code The code is as follows:

// Initialize arrays for filtered and escaped data, respectively.
$clean = array();
$sql = array();
// Filter the name. (For simplicity, we require alphabetic names.)
if (ctype_alpha($_GET['name'])) {
$clean['name'] = $_GET['name'];
} else {
/ / The name is invalid. Do something here.
}
// Escape the name.
$sql['name'] = mysql_real_escape_string($clean['name']);
// Construct the query.
$query = "SELECT *
FROM users
WHERE name = '{$sql['name']}'";
?>

Another effective way to prevent SQL injection is to use prepare statements, such as:
Copy code The code is as follows:

< ;?php
// Provide the query format.
$query = $db->prepare('SELECT *
FROM users
WHERE name = :name');
// Provide the query data and execute the query.
$query->execute(array('name' => $clean['name']));
?>

2. Understand the difference between comparison operators
For example, you use strpos() to detect whether a substring exists in a string (if the substring is not found, the function returns FALSE ), the result may result in an error:
Copy code The code is as follows:

$authors = 'Chris & Sean';
if (strpos($authors, 'Chris')) {
echo 'Chris is an author.';
} else {
echo 'Chris is not an author.';
}
?>

In the above example, since the substring is at the very beginning, the strpos() function correctly returns 0, indicating that the substring At the very beginning of the string. Then, because the conditional statement treats the result as a Boolean (Boolean) type, 0 is calculated as FALSE by PHP, which ultimately causes the conditional statement to fail.
Of course, this BUG can be corrected using strict comparison statements:
Copy code The code is as follows:

if (strpos($authors, 'Chris') !== FALSE) {
echo 'Chris is an author.';
} else {
echo 'Chris is not an author .';
}
?>

3. Shortcut the else (Shortcut the else)
Remember, always before you use a variable You need to initialize them first.
Consider the following conditional statement to detect whether the user is an administrator based on the username:
Copy the code The code is as follows:

if (auth($username) == 'admin') {
$admin = TRUE;
} else {
$admin = FALSE;
}
?>

This one seems safe enough because it’s easy to understand at a glance. Imagine a more complex example that sets variables for both name and email, for convenience:
Copy code The code is as follows:

if (auth($username) == 'admin') {
$name = 'Administrator';
$email = 'admin@example.org' ;
$admin = TRUE;
} else {
/* Get the name and email from the database. */
$query = $db->prepare('SELECT name, email
FROM users
WHERE username = :username');
$query->execute(array('username' => $clean['username']));
$result = $ query->fetch(PDO::FETCH_ASSOC);
$name = $result['name'];
$email = $result['email'];
$admin = FALSE;
}
?>

Because $admin is still explicitly set to TRUE or FALSE, everything seems to be fine. However, if another developer later adds an elseif statement to the code, it is likely that he will forget about it:
Copy code The code is as follows:

if (auth($username) == 'admin') {
$name = 'Administrator';
$email = 'admin@example.org ';
$admin = TRUE;
} elseif (auth($username) == 'mod') {
$name = 'Moderator';
$email = 'mod@example.org ';
$moderator = TRUE;
} else {
/* Get the name and email. */
$query = $db->prepare('SELECT name, email
FROM users
WHERE username = :username');
$query->execute(array('username' => $clean['username']));
$result = $query- >fetch(PDO::FETCH_ASSOC);
$name = $result['name'];
$email = $result['email'];
$admin = FALSE;
$ moderator = FALSE;
}
?>

If a user provides a username that triggers an elseif condition, $admin is not initialized, which may result in an error. Necessary behavior, or worse, a security hole. Additionally, a similar situation exists for the $moderator variable, which is not initialized in the first condition.
It is completely easy to avoid this situation by initializing $admin and $moderator:
Copy code The code is as follows:

$admin = FALSE;
$moderator = FALSE;
if (auth($username) == 'admin') {
$name = ' Administrator';
$email = 'admin@example.org';
$admin = TRUE;
} elseif (auth($username) == 'mod') {
$name = ' Moderator';
$email = 'mod@example.org';
$moderator = TRUE;
} else {
/* Get the name and email. */
$query = $db->prepare('SELECT name, email
FROM users
WHERE username = :username');
$query->execute(array('username' => $clean[' username']));
$result = $query->fetch(PDO::FETCH_ASSOC);
$name = $result['name'];
$email = $result['email '];
}
?>

Whatever the rest of the code is, it is now clear that $admin is FALSE unless it is explicitly set to something else. . The same goes for $moderator. The worst thing that can happen is that $admin or $moderator are not modified under any conditions, resulting in someone who is an administrator or moderator not being treated as the corresponding administrator or moderator.
If you want to shortcut something, and you feel a little disappointed to see that our examples include else. We have a bonus tip you might be interested in. We're not sure it can be considered a shortcut, but we hope it's still helpful.
Consider a function that detects whether a user is authorized to view a particular page:
Copy the code The code is as follows:

function authorized($username, $page) {
if (!isBlacklisted($username)) {
if (isAdmin($username)) {
return TRUE ;
} elseif (isAllowed($username, $page)) {
return TRUE;
} else {
return FALSE;
}
} else {
return FALSE ;
}
}
?>

This example is quite simple, as there are only three rules to consider:
administrators are always allowed access,
Those in the blacklist are always prohibited from accessing.
isAllowed() determines whether others have access.
(There is also a special case: when an administrator is in the blacklist, but this seems unlikely, so we will ignore this situation here).
We use functions to make this judgment to keep the code simple and focus on the business logic.
For example:
Copy code The code is as follows:

function authorized($username, $page) {
if (!isBlacklisted($username)) {
if (isAdmin($username) || isAllowed( $username, $page)) {
return TRUE;
} else {
return FALSE;
}
} else {
return FALSE;
}
}
?>

In fact, you can reduce the entire function to a compound condition:
Copy code Code As follows:

function authorized($username, $page) {
if (!isBlacklisted($username) && (isAdmin($username) || isAllowed( $username, $page)) {
return TRUE;
} else {
return FALSE;
}
}
?>

Finally , this can be reduced to only one return:
Copy code The code is as follows:

function authorized($username, $page) {
return (!isBlacklisted($username) && (isAdmin($username) || isAllowed($username, $page));
}
?>

If your goal is to transcribe the number of lines of code, then you can do it. However, you should notice that we are using isBlacklisted(), isAdmin() and isAllowed(). Depending on what's involved, reducing the code to just a single compound condition may not be attractive.
Now comes our little trick, an "immediate return" function, so if you return as soon as possible, You can express these rules very simply:
Copy the code The code is as follows:

function authorized ($username, $page) {
if (isBlacklisted($username)) {
return FALSE;
}
if (isAdmin($username)) {
return TRUE;
}
return isAllowed($username, $page);
}
?>

This example uses more lines of code, but it is very simple and unobtrusive. More importantly, this approach reduces the amount of context you have to consider. For example, once you determine whether a user is blacklisted, you can safely forget about it. This is quite helpful especially if your logic is complex.
4. Always use braces
PS: Forgiveness means "Drop Those Brackets"
According to the content of this article, our corresponding author should mean "braces" ," rather than brackets. "Curly brackets" may mean curly brackets, but "brackets" usually means "square brackets." This tip should be unconditionally ignored because, without curly braces, readability and maintainability are destroyed.
Give a simple example:
Copy code The code is as follows:

if ( date('d M') == '21 May')
$birthdays = array('Al Franken',
'Chris Shiflett',
'Chris Wallace',
'Lawrence Tureaud' );
?>

If you're good enough, smart enough, secure enough, notorious enough, or pitied enough, you might want to attend a social gathering on May 21st:
Copy code The code is as follows:

if (date('d M') == '21 May')
$birthdays = array('Al Franken',
'Chris Shiflett',
'Chris Wallace',
'Lawrence Tureaud');
party(TRUE) ;
?>

Without braces, this simple condition leads you to social gatherings every day. Maybe you have perseverance and therefore this mistake is a welcome one. Hopefully that silly example doesn't distract from the point that excessive partying can have an unexpected side effect.
To advocate dropping braces, previous articles used short statements like the following as examples:
Copy code The code is as follows:

if ($gollum == 'halfling') $height --;
else $height ++;
?>

Because each condition is placed on a separate line, this error may seem to occur less frequently, but this will lead to another problem: the code will be inconsistent and require more time to read and understand. Consistency is such an important characteristic that developers often adhere to a coding standard even if they don't like the coding standard itself.
We advocate always using braces:
Copy code The code is as follows:

if (date('d M') == '21 May') {
$birthdays = array('Al Franken',
'Chris Shiflett' ,
'Chris Wallace',
'Lawrence Tureaud');
party(TRUE);
}
?>

It doesn’t matter if you party every day Yes, but make sure this is well thought out, and please be sure to invite us!
5. Try to use str_replace() instead of ereg_replace() and preg_replace()
We hate it Hear the word of denial, but (sic) this little trick used to demonstrate misuse leads to the same abuse problem it was trying to avoid. (
We hate to sound disparaging, but this tip demonstrates the sort of misunderstanding that leads to the same misuse it's trying to prevent.)
It is obvious that string functions are faster and more efficient at character matching than regular expression functions , but the author's attempt to draw a corollary from this fails miserably :)
If you're using regular expressions, then ereg_replace() and preg_replace() will be much faster than str_replace().
Because str_replace() does not support pattern matching, this statement makes no sense. The choice between string functions and regular expression functions comes down to which is fit for purpose, not which is faster. If you need to match a pattern, use a regular expression function. If you need to match a string, use a string function.

6. Use the ternary operator The benefits of the ternary operator are worth discussing. Here is a line taken from a recent audit we conducted:

Copy code The code is as follows:
$host = strlen($host) > 0 ? $host : htmlentities($ host);
?>

Ah, the author’s true intention was to escape $host if the length of the string is greater than 0, but he accidentally did the opposite. An easy mistake to make, right? Maybe. Easy to miss during code audit? certainly. Simplicity doesn't necessarily make code great.
The triple operator is also suitable for single rows, prototypes, and templates, but we believe that a plain conditional statement is always better. PHP is descriptive and detailed, and we think code should be too.

7. Memcached
Disk access is slow, network access is also slow, and databases usually use both.
Memory is fast. Using a local cache avoids the overhead of network and disk access. Combine these principles, and you have memcached, a "distributed memory object caching system" originally developed for the Perl-based blogging platform LiveJournal.
If your application is not distributed across multiple servers, you may not need memcached. Single caching method - serialize the data and save it in a temporary file. For example – a lot of redundant work can be eliminated for each request. In fact, this is the type of low-hanging fruit we consider when helping our customers optimize their applications.
What is low-hanging fruit:
A fruit-bearing tree often contains some branches low enough for animals and humans to reach without much effort. The fruit contained on these lower branches may be not be as ripe or attractive as the fruit on higher limbs, but it is usually more abundant and easier to harvest. From this we get the popular expression “low hanging fruit”, which generally means selecting the easiest targets with the least amount of effort. The simplest and most common way to cache data in memory is to use the shared type helper methods in APC, a caching system originally developed by our colleague George Schlossnagle. Consider the following example:


Copy code The code is as follows:
$feed = apc_fetch('news');
if ($feed === FALSE) {
$feed = file_get_contents('http://example.org/news.xml');
// Store this data in shared memory for five minutes.
apc_store('news', $feed, 300);
}
// Do something with $feed.
?>


With this type of caching, you don’t have to wait for the remote server to send feed data on every request. Some latency is incurred - in this example the upper limit is five minutes, but this can be adjusted to near real-time depending on your application needs.
8. Use a framework
All decisions have consequences, we love frameworks - in fact, the lead developers of CakePHP and Solar work with us at OmniTI - but use a framework It doesn't magically make what you're doing better.
In October, our colleague Paul Jones wrote an article for HP Advent called The Framework as Franchise, in which he compared frameworks to commercial franchises. He quotes advice from Michael Gerber's book "The E-Myth Revisited":
Gerber points out that to run a successful business, the entrepreneur needs to act like he is going to sell his business as a Acts like the franchise's archetypes. This is the only way a business owner can make the business run without being personally involved in every decision.
( Gerber notes that to run a successful business, the entrepreneur needs to act as if he is going to sell his business as a franchise prototype. It is the only way the business owner can make the business operate without him being personally involved in every decision.)
This is good advice. Whether you plan to use a framework or define your own tags and conventions, it's important to see the value from a future developer's perspective.
While we would love to give you a one-size-fits-all truth, stretching the idea to show that a framework is always appropriate is not what we want to do.
If you ask us if we should use a framework, the best answer we can give is, "It depends."
9. Correct use of error suppression operators
Always try to avoid using error suppression operator symbols. In a previous article, the author stated:
The @ operator is quite slow and can be very expensive if you need to write high-performance code.
Error suppression is slow because PHP dynamically changes the error_reporting level to 0 before executing the suppression statement, and then immediately restores it. This costs money.
Worse yet, using error suppressors makes it difficult to track down the root cause of the problem.
The previous article used the following example to support assigning a value to a variable by reference. . . (How to translate this sentence? I’m confused~~~)
The previous article uses the following example to support the practice of assigning a variable by reference when it is unknown if $albus is set:
Copy code The code is as follows:

$albert =& $albus;
?>

While this works - for now - relying on strange, undefined behavior, having a good understanding of why this works is a good way to generate bugs.
Because $albert refers to $albus, later modifications to $albus will also affect $albert.
A better solution is to use isset() and add braces:
Copy code The code is as follows:

if (!isset($albus)) {
$ albert = NULL;
}
?>

Assigning NULL to $albert has the same effect as assigning it a non-existent reference, but it is more clear and greatly improved Improves code clarity and avoids reference relationships between two variables.
If you inherit code that uses the error suppression operator excessively, we've got a bonus tip for you. There is a new PECL extension called Scream that disables error suppression.
10. Use isset() Instead of strlen()
this is actually a neat approach, although the previous article didn't explain this at all. The following is a supplementary example:
Copy code The code is as follows:

if (isset($ username[5])) {
// The username is at least six characters long.
}
?>

When you treat a string as an array (no lights in the wilderness: in fact, in C language, characters usually exist in the form of arrays), each character in the string is an element of the array. By checking for the presence or absence of a specific element, you can check whether the string has at least that many characters present. (Note that the first character is element 0, so $username[5] is the 6th character in $username.)
The reason why using isset in this way is slightly faster than strlen is complicated. The simple explanation is that strlen() is a function and isset() is a syntactic structure. Generally speaking,
calling a function is more expensive than using language constructs.
About the author:
Hi, we are Chris Shiflett and Sean Coates. We both work at OmniTI ("the most important web company you've never heard of"), blog about PHP and other stuff at shiflett.org and seancoates.com, curate PHP Advent, and do the Twitter thing as @shiflett and @coates.
Translation FROM: http://coding.smashingmagazine.com/2009/03/24/10-useful-php-tips -revisited/

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/324064.htmlTechArticle1. Use a SQL injection cheat sheet. A basic principle is to never trust user-submitted data. Another rule is to escape data when you send or store it (...
Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
What is the difference between unset() and session_destroy()?What is the difference between unset() and session_destroy()?May 04, 2025 am 12:19 AM

Thedifferencebetweenunset()andsession_destroy()isthatunset()clearsspecificsessionvariableswhilekeepingthesessionactive,whereassession_destroy()terminatestheentiresession.1)Useunset()toremovespecificsessionvariableswithoutaffectingthesession'soveralls

What is sticky sessions (session affinity) in the context of load balancing?What is sticky sessions (session affinity) in the context of load balancing?May 04, 2025 am 12:16 AM

Stickysessionsensureuserrequestsareroutedtothesameserverforsessiondataconsistency.1)SessionIdentificationassignsuserstoserversusingcookiesorURLmodifications.2)ConsistentRoutingdirectssubsequentrequeststothesameserver.3)LoadBalancingdistributesnewuser

What are the different session save handlers available in PHP?What are the different session save handlers available in PHP?May 04, 2025 am 12:14 AM

PHPoffersvarioussessionsavehandlers:1)Files:Default,simplebutmaybottleneckonhigh-trafficsites.2)Memcached:High-performance,idealforspeed-criticalapplications.3)Redis:SimilartoMemcached,withaddedpersistence.4)Databases:Offerscontrol,usefulforintegrati

What is a session in PHP, and why are they used?What is a session in PHP, and why are they used?May 04, 2025 am 12:12 AM

Session in PHP is a mechanism for saving user data on the server side to maintain state between multiple requests. Specifically, 1) the session is started by the session_start() function, and data is stored and read through the $_SESSION super global array; 2) the session data is stored in the server's temporary files by default, but can be optimized through database or memory storage; 3) the session can be used to realize user login status tracking and shopping cart management functions; 4) Pay attention to the secure transmission and performance optimization of the session to ensure the security and efficiency of the application.

Explain the lifecycle of a PHP session.Explain the lifecycle of a PHP session.May 04, 2025 am 12:04 AM

PHPsessionsstartwithsession_start(),whichgeneratesauniqueIDandcreatesaserverfile;theypersistacrossrequestsandcanbemanuallyendedwithsession_destroy().1)Sessionsbeginwhensession_start()iscalled,creatingauniqueIDandserverfile.2)Theycontinueasdataisloade

What is the difference between absolute and idle session timeouts?What is the difference between absolute and idle session timeouts?May 03, 2025 am 12:21 AM

Absolute session timeout starts at the time of session creation, while an idle session timeout starts at the time of user's no operation. Absolute session timeout is suitable for scenarios where strict control of the session life cycle is required, such as financial applications; idle session timeout is suitable for applications that want users to keep their session active for a long time, such as social media.

What steps would you take if sessions aren't working on your server?What steps would you take if sessions aren't working on your server?May 03, 2025 am 12:19 AM

The server session failure can be solved through the following steps: 1. Check the server configuration to ensure that the session is set correctly. 2. Verify client cookies, confirm that the browser supports it and send it correctly. 3. Check session storage services, such as Redis, to ensure that they are running normally. 4. Review the application code to ensure the correct session logic. Through these steps, conversation problems can be effectively diagnosed and repaired and user experience can be improved.

What is the significance of the session_start() function?What is the significance of the session_start() function?May 03, 2025 am 12:18 AM

session_start()iscrucialinPHPformanagingusersessions.1)Itinitiatesanewsessionifnoneexists,2)resumesanexistingsession,and3)setsasessioncookieforcontinuityacrossrequests,enablingapplicationslikeuserauthenticationandpersonalizedcontent.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.