[PHP] Website

User Registration


On first page load of user registration:

1. [Security] Domain check

if ($_SERVER['HTTP_HOST'] != 'domain'){
  exit('Disallowed domain.');
}

2. Login session check (Force redirect to main page if logged in)

if($_SESSION['session_id']){
    header('Location: '.$url);
    exit;
}

3. SSL-related handling

if(!isset($_SERVER["HTTPS"])){
    $url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header('Location: '.$url);
}


4. i-PIN authentication, Identity verification (mobile phone)

In this case, use a form tag to generate the related request and process the returned value.


5. Terms of Service agreement

Use JavaScript to verify if the corresponding checkbox is checked before proceeding.

Login

1. Submit login data

: Use a form tag to submit ID and password.

2. [Security] Domain check

if ($_SERVER['HTTP_HOST'] != 'domain'){
  exit('Disallowed domain.');
}

3. Prevent submission of form data generated externally

function referer(){

	$http_referer = str_replace('http://','',$_SERVER['HTTP_REFERER']);
	$http_referer = str_replace('https://','',$http_referer);

	$referer = explode('/',$http_referer);

	if ($referer[0] <> $_SERVER['HTTP_HOST']) {

		// Easier to process with a script that triggers a warning popup echo '....';
		exit;
	}

}

4. Verify submitted values

$user_id = trim( $_POST['userid'] );

$user_id= $mysqli_accountdb_s1->real_escape_string( $userid );// SQL injection prevention

$pw = trim( $_POST['password'] );

$backurl = trim( $_POST['backurl'] );
if (!$backurl) {
	$backurl = trim( $_GET['backurl'] ); // URL to return to after login completion
}
$backurl = xss_replace($backurl); // String processing via XSS prevention function

if (!$backurl) {
	$backurl = 'Set main address'; // If no return URL, set to main address
}

5. Hashing

$encode_pw = sha1($pw);


6. Handle sequential login delay using sessions

if($_SESSION['ss_logintime'] != '') {
	$chk_time = mktime(date("H"),date("i"),date("s")-10,date("m"),date("d"),date("Y"));

	if ($chk_time < strtotime($_SESSION['ss_logintime'])) {
		$msg = "Login is in progress. Please wait a moment.";
		msg($msg); // Display notification
		ob_flush();
		flush();
		sleep(2);
	}
}

$_SESSION['ss_logintime'] = date('Y-m-d H:i:s');

7. IP check

IP check using cookies + login count limit (under 10 times) > 10-minute restriction (process by storing login time in cookie).

8. Login macro check

Prevent hacking using brute-force attacks.

9. Real user check

Check if the user exists, is not a withdrawn member, and the password is correct — this part can be checked via query or within PHP.

10. Overseas IP block user check

Prevent circumvented hacking via overseas IP blocking.

11. Login failure count accumulation: block login after 5 or more failures > redirect to password recovery

Redirect to password recovery page if login failure count is 5 or more.

12. Begin login

Create session.

13. Update user's final login information

session_id, login failure count, login date, login IP.

14. Add to login history

Record login history in the login history table.

15. Check for simple members/Facebook members

Forced redirect to the full membership conversion menu.

16. Password change check

Check if 90 days have passed since the last password change.

MySQL

1. auto_increment value increases even when an Insert fails.

In reality, even if records are not stored due to errors like duplicates after executing an insert query using MySQLi, the corresponding auto_increment key value increases by +1.

The following article refers to this as a MySQL bug.

(http://desmart.com/blog/be-careful-with-mysqls-auto-increment-how-we-ended-up-losing-data)

QA

1. &#65279

If the following code appears on the output screen and the intended echo value is not displayed: &#65279;

This is an 'encoding issue'.

The solution is to use Notepad++ to re-encode the file to UTF-8 (without BOM).

2. How to execute PHP code in HTML files

(1) Enter the following in the httpd.conf file:

AddHandler application/x-httpd-php .html


(2) Enter the following in the .htaccess file:


AddType application/x-httpd-php .html


3. What is 'global'?

'global' allows you to use a global variable when a variable used in a function has the same name as the global variable.

You can think of it as similar to 'self.variableName' in iOS code.

Reference Notes


[SERVER]

$_SERVER['REQUEST_URI'] = Current page address excluding the domain = index.phpuser=&name=

$_SERVER['PHP_SELF'] = Current page address excluding domain and passed values = index.php

[require or require_once, include or include_once]

Originally, require_once and include_once were used instead of require and include.

The reason for using this API is to avoid duplicate functions.

However, it is said that this API slows down performance.

Therefore, it is recommended to use it as follows:

if (!defined('MyIncludeName')) {
    require('MyIncludeName');
    define('MyIncludeName', 1);
}

Below are the comparison results:



php                  hhvm


if



defined



0.18587779998779



0.046600103378296


require_once


1.2219581604004



3.2908599376678


[Additional TIP]


echo is faster than print.


Single quotes (') are faster than double quotes (") for wrapping strings.

This is because PHP looks for variables within double quotes, but not within single quotes.

Use single quotes if the string does not contain variables.


Use pre-calculated values. When specifying the largest value for a for-loop, don't put it in the loop.

Use $max = count($array) before the for-loop starts.

for($x=0;$x<count($array);$x++) ==> for($x=0;$x<$max;$x++)

To free memory, large arrays should be handled with unset or null processing.

str_replace is faster than preg_replace. str_replace is generally the best, but strstr is sometimes faster for large strings. Using an array inside str_replace is usually faster than using multiple str_replace calls.


else if is faster than switch.


Close database connection after use.


$row['id'] is 7 times faster than $row[id]. If you don't use single quotes, the system has to guess what index you meant.


Use <?php ... ?> when declaring PHP. All other styles are bad practice.



Use strict code; avoid hiding notices, warnings, and errors. It leads to cleaner code and less overhead. Consider always keeping error_reporting(E_ALL) on.



Remember to use exit along with header('location:'.$url); .

Even if the location has changed, the script continues to run.


Initialize variables before use. Otherwise, it is very slow.


The @ symbol, which suppresses errors, is very slow.

It is better to use the GET method for simple SELECT functions, and POST for UPDATE functions.

This is because GET requests are cached and relatively faster (POST requests are not cached).

PHP 5.2.9 cannot interpret the '[ ]' syntax for arrays. Be careful.

If existing source code uses '[ ]' for arrays, it must be changed to array() for version 5.2.9.

Do not use preg_match()

if you only want to check if one string is contained in another string.

Use strpos() or strstr() instead as they will be faster.

</span>

AD