# **Learn PHP** **Cú Pháp** - ``` <?php echo "hello world"; ?> ``` **Phân biệt dấu '' và dấu ""** - * Khi sử dụng dấu **''** thì toàn bộ code trong dấu **''** sẽ là chuỗi VD: ``` <?php $a=1 echo '$a'; ?> Code này sẽ in ra $a ``` * khi sử dụng dấu **""** thì có thể chèn biến vào - VD: ``` <?php $a=1 echo "$a"; ?> Code này sẽ in ra 1 ``` **Comment** - ``` // 'comment dòng' # 'comment dòng' /* */ 'comment đoạn' ``` **Chèn html** - ``` <?php echo "<h1>hello world</h1><br>"; ?> ``` **Biến trong PHP** - * Dùng dấu $ để khai báo biến (Lưu ý **không dùng số** ở đầu tên biến) VD: ``` $a; $b=1; $c="hello world"; echo $b."; ".$c; #dùng dấu . để ngăn cách các biến khi in ra #kết quả: 1; hello world ``` **Hằng trong PHP** - * Để khai báo hằng ra sử dụng hàm **define("tên hằng","giá trị",true or false)**, gía trị true or false có tác dụng giúp tên hằng có phân biệt chữ hoa chữ thường không VD: ``` define("HANG","hello world"); echo HANG; //hello world define("HANG","hello world",true); echo hang; //hello world ``` **Câu lệnh Print** - `print "hello world";` * Phân biệt print và echo: print luôn trả về độ dài in ra là **1** còn echo thì trả về độ dài **thực tế** VD: ``` print "hello" #1 echo "hello" #5 ``` **Câu điều kiện** - ``` if (điều kiện) { kết quả } ``` VD: ``` <?php $a=10; if (a>10){ echo "a>10"; } elseif(a==10){ echo "a=10"; } else{ echo "a<10"; } ?> ``` **Chuỗi** - * Các hàm xử lí chuỗi * strlen() Đếm độ dài chuỗi * str_word_count() Đếm số từ * strrev() Đảo ngược chuỗi * strpos("Chuỗi gốc","Chuỗi cần tìm") tìm kiếm trong chuỗi * str_replace("Chuỗi cần thay trong chiỗi gốc","Chuỗi thay thế","Chuỗi gốc") thay thế trong chuỗi ``` a="THIS IS STRING" echo a; #THIS IS STRING echo strlen(a) //14 echo str_word_count(a) //3 echo strrev(a) //GNIRTS SI ISHT echo strpos(a,"is") //6 echo str_replace("IS","ARE",a) // THIS ARE STRING ``` **Kiểm tra Kiểu dữ liệu** - ``` $a="Hello"; var_dump($a); //string(5)"Hello" $a=10; var_dump($a); //int(10) ``` * Các kiểu dữ liệu * String * Integer * Float (floating point numbers - also called double) * Boolean * Array * Object * NULL * Resource **Toán tử** - `+ - * / % ++ += -=` `>= <= == === !== !===` `&& ||` * **Phân biệt == và ===** * **==** so sánh không quan tâm đến kiểu dữ liệu * **===** so sánh luôn kiểu dữ liệu VD: ``` $a=10; $a="10"; $a==$b // true $a===$b //false ``` **Switch-Case** - ``` <?php $color=1; swich(color){ case 1; echo "red"; break; case 2; echo "blue"; break; case 3; echo "yellow"; break; } ?> ``` **Vòng lặp** - * **Vòng lặp for** ``` for ($i=0;$i<=10;$i++) { echo $i; } ``` * **Vòng lặp while** ``` $i=0; while (i<=10) { echo $i; $i++; } ``` * **Vòng lặp foreach(lặp mảng)** ``` $a=array('1','2','3'); foreach($a as $i) { echo %i; } ``` **Thời gian trong php** - ``` echo date("Y/m/d"); # result: 2024/01/01 echo date("d/m/Y");# result: 01/01/2024 echo date("h:i:s") #result: gio:phut:giay ``` **Kiểm tra biến** - **Hàm empty** * Dùng để kiểm tra giá trị của biến có **rỗng** hay không nếu rỗng thì trả về true ngược lại trả về false ``` <?php $a=10; empty($a) //false $b=""; $c=0; empty($b) //true empty($c) //true ?> ``` **Hàm isset** * Hàm isset() dùng để kiểm tra biến có **tồn tại** hay không ``` <?php $a=10; isset($a) //false ?> ``` ``` <?php isset($a) //true ?> ``` **Function** - ``` function chanle($x) { if ($x%2==0) { return "chan"; } else { return "le"; } } echo chanle(10); // ``` **Mảng** - * **Mảng 1 chiều** ``` $name=array("a","b","c","d"); echo $name[0]; //result: a echo $name[1]; //result: b ``` ``` $name=array("a"=>"1999","b"=>"2000","c"=>"2001","d"=>"2002"); echo $name['a']; //result: 1999 echo $name['c']; //result: 2001 ``` * **Mảng đa chiều** ``` $myarray=array ( array("a","b","c"), array("1","2","3"), ) echo $myarray[0][0]; #result: a echo $myarray[1][1]; #result: 2 ``` * **Hiển thị toàn bộ mảng** ``` $name=array("a","b","c","d"); print_r($name); #result: Array ( [0] => a [1] => b [2] => c [3] => d ) ``` * **Kiểm tra kích thước mảng** ``` $name=array("a","b","c","d"); echo count($name); #result: 4 ``` * **Thêm phần tử vào mảng** ``` $name=array("a","b","c","d"); a[]="f"; #result: ("a","b","c","d","f") ``` * **Xóa phần tử** ``` $name=array("a","b","c","d"); unset($name[0]) #result: ("b","c","d","f") ``` * **Sắp xếp** * **sort** : sắp xếp tăng * **rsort** : sắp xếp giảm ``` sort($name); rsort($name); ``` **Chuyển string sang array** - ``` <?php $a="01/01/2001"; $thoigian=explode("/",$a); print_r($thoigian); #result: Array ([0] => 01 [1] => 01 [2] => 2001 ) ?> ``` **Chuyển array sang string** - ``` $name=array("a","b","c","d"); $s=implode("",$name) echo $s; #result: abcd $s=implode("-",$name) echo $s; #result: a-b-c-d ``` **PHP and JSON** - * JSON là viết tắt của Ký hiệu đối tượng JavaScript và là một cú pháp để lưu trữ và trao đổi dữ liệu. Vì định dạng JSON là định dạng dựa trên văn bản nên nó có thể dễ dàng được gửi đến và đi từ máy chủ và được bất kỳ ngôn ngữ lập trình nào sử dụng làm định dạng dữ liệu. * **json_encode()**: được sử dụng để mã hóa một giá trị sang định dạng JSON. ``` <?php $age = array("Peter"=>35, "Ben"=>37, "Joe"=>43); echo json_encode($age); //result: {"Peter":35,"Ben":37,"Joe":43} ?> ``` * **json_decode()**: được sử dụng để giải mã một đối tượng JSON thành một đối tượng PHP hoặc một mảng kết hợp. ``` <?php $jsonobj = '{"Peter":35,"Ben":37,"Joe":43}'; var_dump(json_decode($jsonobj)); ?> //result: object(stdClass)#1 (3) { ["Peter"]=> int(35) ["Ben"]=> int(37) ["Joe"]=> int(43) } ``` **Chuyển Trang** - * Ví dụ khi ta truy cập vào trang **index.php** nó sẽ tự động chyển hướng sang trang **xuli.php** ``` #index.php <?php header('location: xuli.php'); ?> ``` **Biến toàn cục** - * **Biến toàn cục có thể truy cập từ bất kì đâu trong code** * **$GLOBALS** ``` <?php $a=10; function test1(){ return $GLOBALS['a']; } echo test1(); //result: 10 function test2(){ $GLOBALS['c']=10; } test2(); echo $c; //result: 10; ?> ``` * **$_POST** ``` #Code html <form action="index.php" method="post"> <input type="email" name="email" id=""> <input type="password" name="password" id=""> <br> <input type="submit" name="submit" value="submit"> </form> #Code php <?php echo $_POST['email']." ".$_POST['password']; ?> ``` * **$_GET** ``` #Code html <form action="index.php" method="GET"> <input type="email" name="email" id=""> <input type="password" name="password" id=""> <br> <input type="submit" name="submit" value="submit"> </form> #Code php <?php echo $_GET['email']." ".$_GET['password']; ?> ``` * **$_REQUEST (REQUEST có thế thay thế get và post)** ``` echo $_REQUEST['email']."-".$_REQUEST['password']; ``` **Gộp file** - **Require and Require_once** xuli.php ``` <?php echo "this is file xuli.php"; ?> ``` index.php ``` <?php require("xuli.php"); echo "this is file index.php"; ?> #result: this is file xuli.php this is file index.php ``` Phân biệt require và require_once - Require được lặp lại 1 file nhiều lần - Require_once chỉ 1 lần duy nhất VD: ``` #require <?php require("xuli.php"); require("xuli.php"); echo "this is file index.php"; ?> #result: this is file xuli.php this is file xuli.php this is file index.php ``` ``` #require_once <?php require_once("xuli.php"); require_once("xuli.php"); echo "this is file index.php"; ?> #result: this is file xuli.php this is file index.php ``` **include và include_once** * Hoạt động tương tự require và require_once VD: ``` #include <?php include("xuli.php"); include("xuli.php"); echo "this is file index.php"; ?> #result: this is file xuli.php this is file xuli.php this is file index.php ``` ``` #include_once <?php include_once("xuli.php"); include_once("xuli.php"); echo "this is file index.php"; ?> #result: this is file xuli.php this is file index.php ``` **Sự khác nhau giữa require và include** * include : **cho phép** thực thi code bên dưới nếu file include không tồn tại * require : **không cho phép** thực thi code bên dưới nếu file include không tồn tại * VD: không tồn tại file test.php ``` #include <?php include("test.php"); echo "this is file index.php"; ?> #result: error this is file index.php ``` ``` #require <?php require("test.php"); echo "this is file index.php"; ?> #result: error ``` **Điều kiện Form** - ``` <?php $nameError = ""; if (empty($_POST['username'])) { $nameError = "khong de trong"; } else { if (!preg_match("/^[a-zA-Z0-9]*$/",$_POST['username'])) { $nameError = "khong duoc nhap ky tu da biet"; } else { echo $_POST['username']; } } ?> <form action="index.php" method="post"> <input type="text" name="username"> <span style="color: red"class="error"><?php echo $nameError ?></span> <br> <input type="submit" value="submit" name="submit"> </form> ``` **Xử lí file** - **1. Đọc file** * Cách 1: ``` <?php echo readfile("file.txt"); ?> ``` * Cách 2: ``` <?php $filename="file.txt"; $myfile=fopen($filename,"r") or die("error"); echo fread($myfile,filesize($filename)); // Đọc toàn bộ file echo fgets($myfile); // Đọc 1 dòng fclose($myfile); ?> ``` * Vòng lặp file ``` <?php $filename="file.txt"; $myfile=fopen($filename,"r") or die("error"); while (!feof($myfile)) { echo fgets($myfile); } fclose($myfile); //đóng file ?> ``` **2. Tạo file** ``` <?php $filename="hello.txt"; $myfile=fopen($filename,"w"); ?> ``` **3. Xóa File** * **unlink("đường dẫn")** ``` $xoafile = unlink("./img/test.png"); if ($xoafile) { echo "File bị xóa thành công!"; } else { echo "Error: File không bị xóa."; } ``` **4. Viết vào file** ``` <?php $filename="hello.txt"; $myfile=fopen($filename,"a"); fwrite($myfile,"Hello world"); fclose($myfile); ?> ``` * fopen($filename,"**a**") tùy chọn **a** ghi vào cuối file * fopen(...,"**w**") tùy chọn **w** ghi đè lên file cũ **5. Upload file** ``` <form action="index.php" method='POST' enctype="multipart/form-data"> <input type="file" name="picture" id="" value="Choose"> <input type="submit" name="btn" value="Login"> </form> <?php $a=$_FILES['picture']; print_r($a); ?> //result: Array ( [name] => Screenshot (1).png [type] => image/png [tmp_name] => C:\xampp\tmp\php607E.tmp [error] => 0 [size] => 591877 ) ``` print_r($_FILES['picture']["name"]); //in ra tên file print_r($_FILES['picture']["type"]); //in ra loại file print_r($_FILES['picture']["tmp_name"]); //in ra đường dẫn print_r($_FILES['picture']["error"]); print_r($_FILES['picture']["size"]); //in ra kích thước file * **Upload file vào thư mục** * move_uploaded_file("Đường dẫn thư mục upload","thư mục cần lưu"."tên file sẽ lưu"); ``` <?php if (isset($_FILES['picture'])) { if ($_FILES['picture']["size"]==0){ echo "File is empty"; } else { move_uploaded_file($_FILES['picture']["tmp_name"],'./'.$_FILES['picture']["name"]); } } ?> ``` * **Kiểm tra file đã tồn tại hay chưa** ``` $thumuc='/img/'; $file=$thumuc.basename($_FILES['picture']["name"]); if (file_exists($file)){ echo "File da ton tai"; } else { echo "File chua co"; } ``` **COOKIE** - * **Tạo cookie: setcookie("tên cookie", "giá trị","thời gian","đường dẫn");** `setcookie($name,$value,time()+(86400),"/"); //time()+(86400)=30 ngày` * **Kiểm tra cookie đã tồn tại hay chưa** `isset($name)` * **Xóa cookie** `setcookie($name,$value,time()-(86400),"/");` **SESSION** - ``` <?php session_start(); //Tạo session $_SESSION["name"]="Hacker"; //Tạo session echo $_SESSION["name"]; //in ra session unset($_SESSION["name"]) //Xóa session ?> ``` **Lọc dữ liệu** - * **Lọc chuỗi** ``` $a="hello world"; $b=filter_var($a, FILTER_SANITIZE_STRING); echo $b; ``` * **Lọc số nguyên(Kiểm tra có phải là số nguyên không)** ``` $a='123465'; if (!filter_var($a, FILTER_VALIDATE_INT)==false) { echo "la so nguyen"; } else { echo "khong la so nguyen"; } ``` * **Lọc ip(Kiểm tra xem có phải địa chỉ ip không)** ``` $ip='192.168.1.7.0;ls'; if (!filter_var($ip, FILTER_VALIDATE_IP)==false) { echo "la dia chi ip"; } else { echo "khong la dia chi ip"; } ``` * **Lọc email(Kiểm tra xem có phải địa chỉ mail không)** ``` $mail="hacker@gmail.com"; if (!filter_var($mail, FILTER_VALIDATE_EMAIL)==false) { echo "la dia chi gmail"; } else { echo "khong la dia chi gmail"; } ``` * Lọc url(Kiểm tra xem có phải địa chỉ url không) ``` $url="http://google.com"; $url=filter_var($url, FILTER_SANITIZE_URL); if (!filter_var($url, FILTER_VALIDATE_URL)==false) { echo "url hop le"; } else { echo "url khong hop le"; } ``` **Page_layout** - ``` <a href="index.php?page_layout=trangchu">trangchu</a> <a href="index.php?page_layout=sanpham">sanpham</a> <a href="index.php?page_layout=giohang">giohang</a> <?php if (isset($_GET["page_layout"])) { switch ($_GET["page_layout"]){ case "trangchu"; include_once("trangchu.php"); break; case "sanpham"; include_once("sanpham.php"); break; case "giohang"; include_once("giohang.php"); break; } } ?> ``` **MYSQL** - * **Kết nối database** ``` <?php $server='localhost'; $user='root'; $pass=''; $db='users'; //cach 1 $conn=mysqli_connect($server,$user,$pass,$db); if($conn){ mysqli_query($conn, "SETNAME 'utf8'"); echo "connected"; } else { echo "not connected"; } //cach 2 $conn=new mysqli($server,$user,$pass,$db); if($conn){ echo "connected"; } else { echo "not connected"; } ?> ``` * **Tạo database** ``` <?php $server='localhost'; $user='root'; $pass=''; $db='users'; $conn=mysqli_connect($server,$user,$pass,$db); if($conn){ mysqli_query($conn, "SETNAME 'utf8'"); echo "connected"; } else { echo "not connected"; } $sql='Create database test'; if (mysqli_query($conn,$sql)){ echo "created database test"; } else { echo "can't create database test"; } ?> ``` * **Lấy dữ liệu database** * mysqli_num_rows($result) : in ra số hàng ``` $sql='SELECT * FROM user'; $result=mysqli_query($conn,$sql); if (mysqli_query($conn,$sql)){ if ( mysqli_num_rows($result)>0){ while($row=mysqli_fetch_array($result)){ echo $row['id']." | ".$row['username']." | ".$row['password']; echo"<br>"; } } } else { echo "faild"; } ``` * **Lấy id sản phẩm** ``` <?php $server='localhost'; $user='root'; $pass=''; $db='users'; $conn=mysqli_connect($server,$user,$pass,$db); $sql='SELECT * FROM user'; $result=mysqli_query($conn,$sql); if (mysqli_query($conn,$sql)){ if ( mysqli_num_rows($result)>0){ while($row=mysqli_fetch_array($result)){ ?> <a href="index.php?id=<?php echo $row['id'] ?>">delete</a> <?php } } } else { echo "faild"; } ?> ``` **Bảo mật trong php** - **1. Các lỗ hổng bảo mật phổ biến** * **SQL Injection (SQLi) :** Đây là lỗ hổng gặp phải khi dữ liệu đầu vào không được kiểm soát một cách chặt chẽ, những giá trị đầu vào đó có thể khiến cho việc thực thi mã SQL trở nên không an toàn * **Cross-Site Scripting (XSS) :** XSS cũng là một lỗi xảy ra khi các lập trình viên không kiểm soát tốt dữ liệu đầu vào của người dùng, khi hiển thị những dữ liệu đầu vào mà không kiểm soát kỹ càng người dùng có thể thực thi các mã JavaScript độc hại gây phát sinh lỗi cho hệ thống * **Cross-Site Request Forgery (CSRF) :** Đây là kỹ thuật tấn công khi người dùng không thao tác nhưng kẻ tấn công lại có thể giả mạo các yêu cầu (request) được gửi từ máy của người dùng. * **File Inclusion Vulnerabilities :** Việc sử dụng các hàm như include hoặc require mà dữ liệu đầu vào không có sự kiểm soát nhất định thì cũng có thể gây ra những lỗ hổng cho phép tấn công bằng cách chèn mã độc vào những tập tin này. * **Insecure Session Management :** Người tấn công có thể chiếm đoạt phiên đăng nhập không an toàn của người dùng thông qua đó giả mạo danh tính người dùng * **Insecure Direct Object References (IDOR) :** Cần kiểm tra quyền truy cập của người dùng một cách chính xác, việc này rất quan trọng trong việc kiểm soát các đối tượng người dùng có thể truy cập phù hợp với quyền của mình * **Remote Code Execution (RCE) :** Việc có khả năng thực thi mã từ xa thường xảy ra khi ứng dụng chấp nhận các đầu vào không an toàn và thực thi nó mà không kiểm tra chúng một cách thích hợp **2 .SQL Injection (SQLi)** * Lỗ hổng này thường xuất hiện khi ứng dụng PHP không kiểm soát được dữ liệu đầu vào từ phía người dùng. Điều này có thể dẫn đến việc người dùng sử dụng lỗi để triển khai tấn công ứng dụng thông qua việc thực thi trái phép các mã SQL không an toàn trên cơ sở dữ liệu. * Ví dụ: Biến **$name** trong câu query sau không được kiểm tra cũng như xử lý trước khi đưa vào câu SQL. ` $sql = "SELECT * FROM posts WHERE name = '" . $name . "'"; ` * Ở đây, chúng ta có rất nhiều cách để có thể xử lý đầu vào trước khi thực thi câu SQL như sử dụng Prepared Statements hoặc Parameterized Queries thay vì chỉ nối chuỗi như trên, hoặc chúng ta cũng có thể sử dụng các hàm như mysqli_real_escape_string() để có thể kiểm soát được dữ liệu từ người dùng nhập vào. ``` // Sử dụng Prepared Statements $stmt = $conn->prepare("SELECT * FROM posts WHERE name = ?"); $stmt->bind_param("s", $name); $stmt->execute(); ``` **3. Cross-Site Scripting (XSS)** * Lỗ hổng XSS cũng là một lỗ hổng xảy ra khi mà dữ liệu đầu vào của người dùng không được kiểm soát đúng cách. Gây nên nguy cơ khi mà người dùng hoàn toàn có thể chèn các mã JavaScript độc hại và thực thi nó trên ứng dụng web trong trình duyệt của người sử dụng. * Ví dụ: Dữ liệu được hiển thị lên trang web mà không được xử lý trước `echo "Welcome, " . $user_input;` * Ở đây cách thông dụng nhất là sử dụng hàm **htmlspecialchars()** để có thể xử lý các ký tự đặc biệt thành các HTML entities trước khi hiển thị dữ liệu nhập từ người dùng. ``` echo "Welcome, " . htmlspecialchars($user_input); ``` **4. Cross-Site Request Forgery (CSRF)** * Đây là lỗ hổng mà những hacker có thể lợi dụng để tạo ra những request giả mạo trên máy khách của người dùng mà không cần sự tương tác của họ. * Ví dụ: Dưới đây là một biểu mẫu có thể bị tận dụng bởi lỗi CSRF ``` <form action='http://stringeex.com/change_password' method='post'> <input type='hidden' name='password' value='malicious_password'> <input type='submit' value='Submit'> </form> ``` * Chúng ta có thể ngăn chặn phương pháp tấn công này bằng cách tạo ra một chuỗi token CSRF để xác thực yêu cầu mỗi khi người dùng gửi request lên server để đảm bảo những thao tác đó là do chính người dùng thao tác, chứ không phải là một cuộc tấn công lợi dụng lỗ hổng CSRF. ``` // Tạo ra token CSRF $token = bin2hex(random_bytes(32)); // Lưu trữ lại token được tạo ra, ở đây chúng ta sẽ lưu vào $SESSION $_SESSION['csrf_token'] = $token; // Kiểm tra token CSRF trước khi xử lý yêu cầu if ($_POST['csrf_token'] === $_SESSION['csrf_token']) { // Xử lý yêu cầu } ``` **Mô hình MVC** -