您现在的位置是:网站首页> PHP

PHP学习笔记

  • PHP
  • 2023-03-19
  • 963人已阅读
摘要

PHP学习笔记

点击打开PHP在线教程

PHP基础

PHP的类

如何使用PHP接收POST的JSON数据

PHP输出JSON

PHP文件上传

PHP文件下载

PHP验证码

浏览器重定向

PHP MySQL

PHP其他数据库

PHP的模版引擎

Smart模版引擎

PHP所有文件指向同一个页面

PHP实现RESTful风格的API实例

深入理解PHP的.htaccess文件

apache本地配置HTTPS

php代码如何加域名授权


PHP基础

强制转换

(int) (double) (string) (bool) (array) (object) (real) (float)

$score=(double)13;

类型自动转换

$total=15;//整型

$count="15";//字符串

$total+=$count //$tital=20 (整型)


判断类型 

is_array(...) 

is_bool(...)

is_float(...) 

is_integer(...)  

is_null(..)  

is_numberic(...) 

is_object(...)

is_resouce(...)

is_scalar(...)

is_string(...)


$value1="hello";

$value2=&$value1

$value2="Good Bye!";

这时候$value1也等于“Good Bye!”


PHP 要输出$使用转义符"\"

print ("\$x=%d",$x);


全局变量

在变量前声明global 

如:

$somevar=15;

function addit(){

global $somevar;

$somevar++;

echo "somevar is $somevar"

}

addit();


还可以用$GLOABLS访问

$GLOBALS["somevar"];


静态变量

function keep_track()

{

static $count=0;

$count++;

echo $count;

echo "<br/>";

}

keep_track();

keep_track();

keep_track();


输出为:

1

2

3


超级全局变量


$GLOBALS['z'] = $GLOBALS['x'] + $GLOBALS['y'];

$_SERVER['REMOTE_ADDR']

其他查看手册


$_GET['cat']="apache";

$_GET["id"]="157";

$_POST["name"]="1111";

$_COOKIE["name"]="111";

setcookie("username","xnlun",time()+3600); //设置Cookie,将Cookie保存3600秒

$a=$_SESSION["nnn"];

//清楚cookie

setCookie('username','',time()-3600);

unset($_COOKIE['username']);

在setCookie函数之前不能有任何的输出否则就会出错

echo "this is a test";

setCookie("username","xnlun");


session_start();

if(isset($_SESSION['username']))

 echo 'username 已经存在';

else

 echo 'username 不存在';


//注销session中信息

unset($_SESSION['username']);


Session存储方式php.ini

[Session]

session.save_handler=files

改为User就是自定义存储方式

用函数设置自定义存储session

bool session_set_save_handler(string opne,string close,string read,string write,string destory,string gc);




常量

define("PI",3.1415926)

$pi2=PI*2;


拼接

$a="4444";

$a.="555";

现在$a="4444555";

$a="hello" . "world";

现在$a="hello world";


大括号

echo "i like {$aa['a']}"


foreach语句

$links=array("1","2","3","4");

foreach($links as $link){

echo $link

}

包括键和值

$links=array("1"=>"1”,"2"=>"2","3"=>"3","4"=>"4");

foreach($links as $title=>$link){

echo $title . $link

}


include包含文件

include "/user/a.php"


包含文件一次

include_once "/.../1.php"


require 是一定包含文件就算再if 里面

require_once


默认参数

function hello($a,$b=12){


}

类型约束

function hello(Customer $customer)

{


}

返回多个值

function hello()

{

//递增可以去除索引

$user[]="a";

$user[]="b";

$user[]="c";

return $user;

}


list($name,$email,$language)=hello();

echo "name:$name,email:$email,language:$language"




数组头添加元素

array_unshift(array array,mixed variable[,mixed variable...])

$states=arrat("a","b","c");

array_unshift($states,"d","e","f");


数组尾加元素

array_push($states,"d,"e","f");


从头删除元素

array_shift

$state=array_shift($states);

//这时候$state="a"


从尾删除元素

array_pop

$state=array_pop($states);

//这时$state="c";


搜索数组内一个特定值

in_array($state,$states)


array_key_exists(key,array array);


array_search("a",$states)


获得数组键

array_keys(array array)


获得数组值

array_values(array array)


遍历数组

key(array array)


while($key=key($states)){


 printf("%s<br/>",$key);

 next($states);

}


移动数组指针

指向下一个

next(array array)

指向前一个

prev(array array)

指向第一个元素

reset(array array)

指向最后一个元素

end(array array)


数组大小

count(array array)


数组排序



字符串

长度

int strlen(string)

字符串比较

int strcmp(string,string)

字符串不区分大小写

int strcasecmp(string,string)

处理字符串大小写

strtolower() 

strtoupper()

字符串第一个字符大写

ucfirst()

字符串中每个单词的首字母变为大写

string ucwords(string)

查找字符串

string strstr(string,string)

$v=strstr("123456","2");

$v会等于"23456";

字符串截取

string substr(string,int start,[int length])

字符串替代

str_replace(search,replace,str,[int &count);



日期

$date=new DateTime();

$date->setDate(2010,5,25);

echo $date->format("F j,Y");

echo $date->format("Y-m-d h:i:sa")

Boolean setTime(integer hour,integer minute,[integer second])

$todayDate=new DateTime('today');

$ss=new DateTime('2010-05-30');




PHP的类

类:

class Appliance{

private $_power;

function setPower($status){

$this->_power+$status;

}

}


$blender=new Appliance;

$blender->setPower("on");


态类成员

class Visitor

{

private static $visitors=0;


function __construct()

{

self::$visitors++;

}

static function getVisitors()

{

return self::$visitors;

}


}


echo Vistors::getVisitors(). "<br/>";




辅助函数

创建类别名 

boolean class_alias(string orgname,string aliasName)

确定类是否存在

boolean class_exists(string class_name)

确定对账上下文

string get_class(object object)

了解类方法

array get_class_methods(classname)

了解类属性

array get_class_vars(string class_name)

了解声明类

array get_declared_classes()

了解对象属性

array get_object_vars(object object)

确定对象的父类

string get_parent_class(object object)

确定接口是否存在

boolean interface_exists(string interface_name)

确定对象类型

boolean is_a(object object,string class_name)

确定对象的子类类型

boolean is_subclass_of(mixed object,string class_name)

确定方法是否存在

boolean method_exits(object object,string method_name)


自动加载对象

function __autoload($class)

{

require-once("classes/$class.class.php");

}


类继承


class Executives extends Employee

{


}


接口

interface IMyInterface

{

 function hello();

 function A();

}


class class_name implements IMyInterface

{

function hello()

{


}

}


抽象类

abstract class class_name

{

//插入属性定义

//插入方法定义


}

命名空间

在类文件前加命名空间

namespace Com\Lib

class Clear

{


}


使用 

require "lib.php"

use Com\Lib as WD

$filter=new WD\Clean();



日志

1.初始化日志

void define_syslog_variables(void);

2.打开日志连接

int openlog(string ident,int option,int facility)

option: LOG_ODELAY|LOG_PERROR|LOG_PID

facility:LOG_USER LOG_MAIL LOG_DAEMON LOG_AUTH LOG_LPTR LOG_LOCALN

3.关闭日志

int closelog(void);

4.向日志目标发送消息

int syslog(int priority,string message)

priority:

LOG_EMERG

LOG_ALERT

LOG_CRIT

LOG_ERR

LOG_WARNING

LOG_NOTICE

LOG_INfO

LOG_DEBUG



异常处理

抛出异常

throw new Exception();

try

{

}

catch(Exception $e)

{

echo "Error".$e.getMessage()

}

catch(....)

{

}




如何使用PHP接收POST的JSON数据

首先我给大家介绍三个重要的知识点:

1、php://input:这是一个只读流,允许我们从请求正文中读取原始数据。无论内容类型如何,它都会在请求的 HTTP 标头之后返回所有原始数据。

2、file_get_contents() 函数:PHP 中的此函数用于将文件读入字符串。

3、json_decode() 函数:该函数接受一个 JSON 字符串并将其转换为 PHP 变量,该变量可以是数组或对象。

想必大家都知道我们可以使用$_POST[]全局变量在 PHP 脚本中接收所有发布数据。但是当我们想要接收 JSON 字符串作为发布数据时,就会显示失败。那么想要接收 JSON 字符串,我们就可以使用"php://input”和file_get_contents()函数来帮助我们将 JSON 数据作为文件接收并将其读入字符串。


下面我们通过具体示例来介绍

使用json_decode()函数对 JSON 字符串进行解码。

// 从请求中获取原始数据

$json = file_get_contents('php://input'); 

// 将其转换为 PHP 对象

$data = json_decode($json)


第一种示例

<?php

$json = '["PHP", "HTML", "javascript"]'; 

$data = json_decode($json);

 

echo $data[0];

输出结果:

PHP


第二种示例

<?php

$json = '{

    "title": "PHP",

    "site": "IIS7站长之家博文"

}';

 

$data = json_decode($json);

 

echo $data->title;

echo "<br>";

 

echo $data->site;

输出:

PHP

IIS7站长之家博文



PHP输出JSON


从5.2版本开始,PHP原生提供json_encode()和json_decode()函数,前者用于编码,后者用于解码

json_encode — 对变量进行 JSON 编码,并返回 value 值的 JSON 形式,例如

<?php

$arr = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);

echo json_encode($arr);

?>

以上代码执行后输出:

{"a":1,"b":2,"c":3,"d":4,"e":5}



PHP 底层已经做了 unicode 处理,如果嫌它不够直观,可以利用 urlencode 和 urldecode 方法绕过这个转码为 unicode 的过程:

$arr = array ('a'=>urlencode('芒果小站'));

echo urldecode(json_encode($arr));

以上代码执行后输出:


{"a":"芒果小站"}

如果输出的还是乱码,就是编码 的问题,再加一句

header("Content-type:text/html;charset='utf-8'");

就可以搞定。



PHP文件上传

move_uploaded_file(string filename,string filename2)

filename1;客户端源文件的文件名及其所在路径

filename2:在服务端的目标文件的文件名及其路径

<input name="upfile" type="file"><BR>


$uploadfile="upfiles/".$_FILES["upfile']['name'];

move_uploaded_file($_FILES['upfile']['tmp_name'],$uploadfile);


$_FILES[]['name'] 客户端源文件名

$_FILES[]['type'] 上传文件的类型

$_FILES[]['size'] 上传文件的字节数

$_FILES[]['tmp_name'] 文件上传后再服务器上的临时存储文件名

$_FILES[]['error'] 文件上传的错误代码



PHP文件下载

header("Content-type:application/octet-stream");

header("content-Disposition:filename=\"".$filename . "\"");

header("Content-length:" . $fsize);

while(!feof($fh))

{

$buffer=fread($fh,2048)

echo $buffer

}



PHP验证码


<!DOCTYPE html>

<html>

<head>

    <meta charset="UTF-8">

    <title>登陆</title>

</head>

<body>

    <form action="./login.php" method="post">

        <img src="image_captcha.php"  onclick="this.src='image_captcha.php?'+new Date().getTime();" width="200" height="200"><br/>

        <input type="text" name="captcha" placeholder="请输入图片中的验证码"><br/>

        <input type="submit" value="验证">

    </form>

</body>

</html>




创建一个PHP文件,接受前端页面传入的验证码信息

<?php

/**

 * 接受用户登陆时提交的验证码

 */

session_start();

//1. 获取到用户提交的验证码

$captcha = $_POST["captcha"];

//2. 将session中的验证码和用户提交的验证码进行核对,当成功时提示验证码正确,并销毁之前的session值,不成功则重新提交

if(strtolower($_SESSION["captchaimg"]) == strtolower($captcha)){

    echo "验证码正确!";

    $_SESSION["captcha"] = "";

}else{

    echo "验证码提交不正确!";

}


创建验证码生成PHP文件

<?php

/**

 * 字母+数字的验证码生成

 */

// 开启session

session_start();

//1.创建黑色画布

$image = imagecreatetruecolor(100, 30);

//2.为画布定义(背景)颜色

$bgcolor = imagecolorallocate($image, 255, 255, 255);

//3.填充颜色

imagefill($image, 0, 0, $bgcolor);

// 4.设置验证码内容

//4.1 定义验证码的内容

$content = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

//4.1 创建一个变量存储产生的验证码数据,便于用户提交核对

$captcha = "";

for ($i = 0; $i < 4; $i++) {

    // 字体大小

    $fontsize = 10;

    // 字体颜色

    $fontcolor = imagecolorallocate($image, mt_rand(0, 120), mt_rand(0, 120), mt_rand(0, 120));

    // 设置字体内容

    $fontcontent = substr($content, mt_rand(0, strlen($content)), 1);

    $captcha .= $fontcontent;

    // 显示的坐标

    $x = ($i * 100 / 4) + mt_rand(5, 10);

    $y = mt_rand(5, 10);

    // 填充内容到画布中

    imagestring($image, $fontsize, $x, $y, $fontcontent, $fontcolor);

}

$_SESSION["captcha"] = $captcha;

//4.3 设置背景干扰元素

for ($$i = 0; $i < 200; $i++) {

    $pointcolor = imagecolorallocate($image, mt_rand(50, 200), mt_rand(50, 200), mt_rand(50, 200));

    imagesetpixel($image, mt_rand(1, 99), mt_rand(1, 29), $pointcolor);

}  

//4.4 设置干扰线

for ($i = 0; $i < 3; $i++) {

    $linecolor = imagecolorallocate($image, mt_rand(50, 200), mt_rand(50, 200), mt_rand(50, 200));

    imageline($image, mt_rand(1, 99), mt_rand(1, 29), mt_rand(1, 99), mt_rand(1, 29), $linecolor);

}  

//5.向浏览器输出图片头信息

header('content-type:image/png');  

//6.输出图片到浏览器

imagepng($image);  

//7.销毁图片

imagedestroy($image);



浏览器重定向

header("location: index.php");


PHP MySQL


<?php

$con = mysql_connect("localhost","peter","abc123");

if (!$con)

  {

  die('Could not connect: ' . mysql_error());

  }


// Create database

if (mysql_query("CREATE DATABASE my_db",$con))

  {

  echo "Database created";

  }

else

  {

  echo "Error creating database: " . mysql_error();

  }


// Create table in my_db database

mysql_select_db("my_db", $con);

$sql = "CREATE TABLE Persons 

(

FirstName varchar(15),

LastName varchar(15),

Age int

)";

mysql_query($sql,$con);


mysql_close($con);

?>





<?php

$con = mysql_connect("localhost","peter","abc123");

if (!$con)

  {

  die('Could not connect: ' . mysql_error());

  }


mysql_select_db("my_db", $con);


mysql_query("INSERT INTO Persons (FirstName, LastName, Age) 

VALUES ('Peter', 'Griffin', '35')");


mysql_query("INSERT INTO Persons (FirstName, LastName, Age) 

VALUES ('Glenn', 'Quagmire', '33')");


mysql_close($con);

?>




<?php

$con = mysql_connect("localhost","peter","abc123");

if (!$con)

  {

  die('Could not connect: ' . mysql_error());

  }


mysql_select_db("my_db", $con);


$result = mysql_query("SELECT * FROM Persons");


while($row = mysql_fetch_array($result))

  {

  echo $row['FirstName'] . " " . $row['LastName'];

  echo "<br />";

  }


mysql_close($con);

?>



PHP其他数据库

pgsql  

启动pgsql的扩展

extendion=php_pgsql.dll

所有操作函数;类mysql 只是前缀是pg_


mssql

启动mssql的扩展

extendion=php_mssql.dll

所有操作函数;类mysql 只是前缀是mssql_


oracle

启动mssql的扩展

extendion=php_oci8.dll

OCIlogon

查阅相关函数


SQLite

启动sqlite的扩展

extendion=php_sqlite.dll

所有操作函数;类mysql 只是前缀是sqlite_


Access操作

$conn=new com("adodb.connection");

$conn->open("driver=microsoft access driver (*.mdb);dbq=d:\mytable.mdb");

$rs=$conn->execute("select * from tablename");

while(!$rs->eof)

{

$rs->fields["name"];

$rs->movenext();


}

$rs->close();


ODBC
$conn=odbc_connect("db","dbadmin","password");

$sql="select * from mytable";

$result=odb_do($conn,$sql);

while(odbc_fecth_row($result))

{

$a=odbc_result($ressult,0);

$b=odbc_result($ressult,1);

}

odbc_close($conn);





PHP的模版引擎

为了找到一个好的模板引擎,我在互联网上进行搜索,目前已经整理出了以下名单:


Smarty

Smarty的特点是将模板编译成PHP脚本,然后执行这些脚本。很快,非常灵活。


Themplate Hierarchy

wordpress使用的模版


ThinkTemplate

这是一个专门为ThinkPHP服务的内置模板引擎。ThinkTemplate是一个使用了XML标签库技术的编译型模板引擎,支持两种类型的模板标签,使用了动态编译和缓存技术,而且支持自定义标签库


Heyes Template Class

一个非常容易使用,但功能强大并且快速的模板引擎,它帮助你把页面布局和设计从代码中分离。


FastTemplate

一个简单的变量插值模板类,它分析你的模板,把变量的值从HTML代码中分离处理。


ShellPage

一个简单易用的类,可以让你的整个网站布局基于模板文件,修改模板就能改变整个站点。


STP Simple Template Parser

一个简单、轻量级并且易于使用的模板分析类。它可以从多个模板中组装一个页面,把结果页面输出到浏览器或者文件系统。


OO Template Class

一个你可以用在自己程序中的面向兑现的模板类。


SimpleTemplate

一个可以创建和结构化网站的模板引擎。它可以解析和编译模板。


bTemplate

短小但是快速的模板类,允许你把PHP逻辑代码从HTML修饰代码中分离。


Savant

一个强大且轻量级的PEAR兼容模板系统。它是非编译型的,使用PHP语言本身做为它的模板语言。


ETS - easy template system

可以使用完全相同数据重组模板的模板系统。


EasyTemplatePHP

适用于你的站点的一个简单但是强大的模板系统。


vlibTemplate

一个快速、全能的模板系统,它包含一个缓存和调试类。


AvanTemplate

多字节安全的模板引擎,占用很少系统资源。它支持变量替换,内容块可以设置显示或隐藏。


Grafx Software’s Fast Template

一个修改版本的Fast Template系统,它包括缓存功能,调试控制台以及沉默去除为赋值块。


TemplatePower

一个快速、简单、功能强大的模板类。主要功能有嵌套的动态块支持,块/文件包含支持以及显示/隐藏未赋值的变量。


TagTemplate

这个库的功能被设计来使用模板文件,同时允许你从HTML文件检索信息。


htmltmpl: templating engine

一个适用于Python和PHP的模板引擎。它面向希望在项目中分离代码和设计的web应用开发人员。


PHP Class for Parsing Dreamweaver templates

一个分析Dreamweaver模板的简单类,被用于Gallery 2 和WordPress的自定义模块中。


MiniTemplator (Template Engine)

针对HTML文件的一个紧凑型模板引擎。对于模板变量和块定义它具有简单的语法。其中块可以嵌套。


Layout Solution

简化网站开发和维护。它拥有常用的变量和页面元素使你不需要重复做页面布局工作。


Cached Fast Template

它已经纳入 FastTemplate ,允许你缓存模板文件,甚至可以在分离的块内容上缓存不同的规格。


TinyButStrong

一个支持MySQL, Odbc, Sql-Server和ADODB的模板引擎。它包含7个方法和两个属性。


Brian Lozier’s php based template engine

只有2K大小,非常快并且是面向对象设计。


WACT

一个从设计中分离代码的模板引擎。


PHPTAL

一个PHP下面的XML/XHTML模板库。







Smart模版引擎

点击进入smarty下载地址

smarty.php:

<?php

    include_once("smarty/Smarty.class.php");

    $smarty = new Smarty();

    $hello = "Hello World";

    $smarty->assign("hello", $hello);

    $smarty->display("smarty.html");

?>


smart.html:


<!DOCTYPE html>

<html>

<head>

    <meta charset="UTF-8">

    <title>Title</title>

</head>

<body>

    {$hello}

</body>


模版语法

循环

{foreach key=key1 ite=item1 from=$array1}

{$key1}

{item1}

{/foreach}


外部文件载入

{include file=$filename}



相信有很多朋友还不知道,可以在smarty模板里调用php的内置函数,我们一起来看看它的用法。

模板书写:


{'param1'|functionName:'param2':'param3'}


php函数原型:


echo functionName('param1','param2','param3');


实例:


{'1234567'|substr:'1':'2'}


下面这个和函数的参数顺序有关系


{'a'|str_replace:'A':'abcd'}


直接延伸到,直接在php中写一个函数调用,不需要注册修改器的.


smarty模板的自定义函数

三个种类插件的用法:


1、变量调解器的用法,

<{$var|myfun:arg1:arg2}>


2、函数的用法(和使用HTML标记很像)

如,

<{myfun color=”red” size=”7” num=”7”}>

在PHP中定义的函数为:

$smarty->registerPlugin(“function”,”myfun”,”one”);

function one($args,$smarty){}   //$args为color=”red” size=”7” num=”7”这些参数组合起来的关联数组,第二个参数是自动接收$smarty对象的,如果不用可不写


3、块函数的用法,

如,

<{myfun color=”red” size=”7”}>内容<{/myfun}>

在PHP中定义的函数为:

$smarty->registerPlugin(“block”,”myfun”,”two”)

Function two($args,$content,$smarty){}   //$args为color=”red” size=”7”这些参数组合起来的关联数组,第二个参数是要显示的”内容”,第三个参数是$smarty对象

有两种做法:

1、  使用smarty对象中的registerPlugin()方法将PHP中的函数注册成smarty中的函数。

2、  就是开发的smarty的插件(以独立的特定文件添加插件)

      1)  声明的位置

      可以在smarty类库中的原有Plugins目录下创建,也可以使用自己指定的目录$smarty->addPluginsDir(目录)   //smarty3中


      2)  文件的命名

      修改器,modifier.修改器名称.php

      函数,  function.函数名称.php

      块函数,block.块函数名称.php


      3)  函数的命名

      修改器,smarty_modifier_修改器名称()

      函数,  smarty_function_函数名称()

      块函数,smarty_block_块函数名称()


      4)  参数的规则

      修改器,smarty_modifier_修改器名称($var,$arg1,$arg2,$arg3)

      函数,  smarty_function_函数名称($args,$smarty)

      块函数,smarty_block_块函数($args,$content,$smarty,$repeat)

      //$repeat参数防止块函数被重复调用,及第一次调用为真,以后为假

      //<{myfun color=”red” size=”7”}>内容<{/myfun}>,第一次myfun为真,第二次<{/myfun}>为假


smart自定义函数例子

<?php

require_once "smarty.config.php";

//自定义一个函数

//调用方法:<{test1 times="4" size="5" con="Hello,Liuyibao!" color="red"}>

function test1($args){

$str="";

for($i=0;$i<$args['times'];$i++){

$str.="<p style='font-size:{$args['size']}em;color:{$args['color']}'>{$args['con']}</p>";

}

return $str;

}

//自定义一个块方式函数

//调用方法<{test1}><{/test1}>

function test2($args,$con){

$str="";

for($i=0;$i<$args['times'];$i++){

$str.="<p style='font-size:{$args['size']}em;color:{$args['color']}'>{$con}</p>";

}

return $str;

}

//定义一个计算方法

function jisuan($args){

switch($args['operate']){

case "+" :$res=$args['num1']-$args['num2'];break;

case "-" :$res=$args['num1']-$args['$num2'];break;

case "*" :$res=$args['num1']*$args['$num2'];break;

case "/" :$res=$args['num1']/$args['$num2'];break;

}

return $res;

}

//注册一下

$smarty->register_function("liuyibao","test1");

//注册块函数

$smarty->register_block("liuyibao2","test2");

//注册函数jisuan

$smarty->register_function("jisuan","jisuan");

//替换变量

$smarty->display("function.tpl");

?>


new Bing给的例子

function smarty_function_hello($params, &$smarty) {

    if (!isset($params['name'])) {

        $params['name'] = 'World';

    }

    return 'Hello ' . $params['name'] . '!';

}

You can then register this function as a plugin in Smarty like this:


$smarty->registerPlugin('function', 'hello', 'smarty_function_hello');

After that, you can use the function in your Smarty template like this:


{hello name="John"}




Here’s an example of how to receive the return value of the hello function in your Smarty template:


{hello name="John"|assign:"greeting"}

{$greeting}

This will output “Hello John!”.



init.inc.php Smart模板引擎初始化文件


<?php

  define('ROOT_PATH', dirname(__FILE__)); //网站根目录

  require ROOT_PATH.'/libs/Smarty.class.php'; //引入 Smart 模板引擎

  $_tpl = new Smarty(); //初始化一个对象

  $_tpl->template_dir = ROOT_PATH.'/tpl/'; //重新设置网站的模板目录

  $_tpl->compile_dir = ROOT_PATH.'./com/'; //重新设置网站的编译文件目录

  $_tpl->config_dir = ROOT_PATH.'/configs/'; //重新设置网站的配置文件目录

  $_tpl->left_delimiter = '<{'; //重新设置网站的左定界符

  $_tpl->right_delimiter = '}>'; //重新设置网站的右定界符

?>



index.php


<?php

  require 'init.inc.php'; //引入模板初始化文件

  global $_tpl;

  $_tpl->display('index.tpl'); //载入模板文件

?>

index.tpl 配置变量的使用方式有两种:

一、<{#配置变量#}>;

二、<{$smart.config.配置变量}>



<{config_load file="view.conf" section="one"}>

<!-- view.conf文件不能写完整路径,因为在初始化文件中已经指定,section="one" 代表加载[one]区域 -->

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>配置文件在模板变量中的使用</title>

</head>

<body>

    <table border="<{#border#}>" align="<{#align#}>" width="<{#tabw#}>">

       <tr bgcolor="<{#bgcolor#}>" align="<{#align#}>">

         <td>aaaa</td>

         <td>aaaa</td>

         <td>aaaa</td>

         <td>aaaa</td>

       <tr>

       <tr>

         <td>aaaa</td>

         <td>aaaa</td>

         <td>aaaa</td>

         <td>aaaa</td>

       <tr>

       <tr>

         <td>aaaa</td>

         <td>aaaa</td>

         <td>aaaa</td>

         <td>aaaa</td>

       <tr>

       <tr>

         <td colspan="<{#colspan#}>" align="<{#align#}>">

            区域变量的显示:

            <{#aa#}><br />

            <{#bb#}><br />

            <{#cc#}><br />

         </td>

       </tr>

    </table>

  </body>

</html>


/configs/view.conf 配置文件

border=2

tabw=600

tabh=500

bgcolor=yellow

align=center

 

[one]

colspan=4

aa=one section

 

[two]

bb=two section

 

[three]

cc=three section



PHP所有文件指向同一个页面

您可以使用.htaccess文件来实现这个功能。.htaccess文件是一个Apache服务器配置文件,它允许您在不更改服务器配置的情况下更改网站的行为。要将所有PHP文件指向一个特定的PHP页面,您可以在.htaccess文件中添加以下代码:


RewriteEngine On

RewriteRule ^(.*)\.php$ /yourpage.php [L]

这将重写所有以.php结尾的URL,将它们指向yourpage.php。如果您想将所有文件都指向一个特定的页面,而不仅仅是PHP文件,您可以使用以下代码:


RewriteEngine On

RewriteRule ^(.*)$ /yourpage.php [L]

这将重写所有URL,将它们指向yourpage.php。



PHP实现RESTful风格的API实例


最近看了一些关于RESTful的资料,自己动手也写了一个RESTful实例,以下是源码


目录详情:


restful/

    Request.php 数据操作类

    Response.php 输出类

    index.php 入口文件

    .htaccess 重写url

Request.php :包含一个Request类,即数据操作类。接收到URL的数据后,根据请求URL的方式(GET|POST|PUT|PATCH|DELETE)对数据进行相应的增删改查操作,并返回操作后的结果:


<?php

 

/**

 * 数据操作类

 */

class Request

{

    //允许的请求方式

    private static $method_type = array('get', 'post', 'put', 'patch', 'delete');

    //测试数据

    private static $test_class = array(

        1 => array('name' => '托福班', 'count' => 18),

        2 => array('name' => '雅思班', 'count' => 20),

    );

 

    public static function getRequest()

    {

        //请求方式

        $method = strtolower($_SERVER['REQUEST_METHOD']);

        if (in_array($method, self::$method_type)) {

            //调用请求方式对应的方法

            $data_name = $method . 'Data';

            return self::$data_name($_REQUEST);

        }

        return false;

    }

 

    //GET 获取信息

    private static function getData($request_data)

    {

        $class_id = (int)$request_data['class'];

        //GET /class/ID:获取某个指定班的信息

        if ($class_id > 0) {

            return self::$test_class[$class_id];

        } else {//GET /class:列出所有班级

            return self::$test_class;

        }

    }

 

    //POST /class:新建一个班

    private static function postData($request_data)

    {

        if (!empty($request_data['name'])) {

            $data['name'] = $request_data['name'];

            $data['count'] = (int)$request_data['count'];

            self::$test_class[] = $data;

            return self::$test_class;//返回新生成的资源对象

        } else {

            return false;

        }

    }

 

    //PUT /class/ID:更新某个指定班的信息(全部信息)

    private static function putData($request_data)

    {

        $class_id = (int)$request_data['class'];

        if ($class_id == 0) {

            return false;

        }

        $data = array();

        if (!empty($request_data['name']) && isset($request_data['count'])) {

            $data['name'] = $request_data['name'];

            $data['count'] = (int)$request_data['count'];

            self::$test_class[$class_id] = $data;

            return self::$test_class;

        } else {

            return false;

        }

    }

 

    //PATCH /class/ID:更新某个指定班的信息(部分信息)

    private static function patchData($request_data)

    {

        $class_id = (int)$request_data['class'];

        if ($class_id == 0) {

            return false;

        }

        if (!empty($request_data['name'])) {

            self::$test_class[$class_id]['name'] = $request_data['name'];

        }

        if (isset($request_data['count'])) {

            self::$test_class[$class_id]['count'] = (int)$request_data['count'];

        }

        return self::$test_class;

    }

 

    //DELETE /class/ID:删除某个班

    private static function deleteData($request_data)

    {

        $class_id = (int)$request_data['class'];

        if ($class_id == 0) {

            return false;

        }

        unset(self::$test_class[$class_id]);

        return self::$test_class;

    }

}


Response.php :包含一个Request类,即输出类。根据接收到的Content-Type,将Request类返回的数组拼接成对应的格式,加上header后输出


<?php

/**

 * 输出类

 */

class Response

{

    const HTTP_VERSION = "HTTP/1.1";

 

    //返回结果

    public static function sendResponse($data)

    {

        //获取数据

        if ($data) {

            $code = 200;

            $message = 'OK';

        } else {

            $code = 404;

            $data = array('error' => 'Not Found');

            $message = 'Not Found';

        }

 

        //输出结果

        header(self::HTTP_VERSION . " " . $code . " " . $message);

        $content_type = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : $_SERVER['HTTP_ACCEPT'];

        if (strpos($content_type, 'application/json') !== false) {

            header("Content-Type: application/json");

            echo self::encodeJson($data);

        } else if (strpos($content_type, 'application/xml') !== false) {

            header("Content-Type: application/xml");

            echo self::encodeXml($data);

        } else {

            header("Content-Type: text/html");

            echo self::encodeHtml($data);

        }

    }

 

    //json格式

    private static function encodeJson($responseData)

    {

        return json_encode($responseData);

    }

 

    //xml格式

    private static function encodeXml($responseData)

    {

        $xml = new SimpleXMLElement('<?xml version="1.0"?><rest></rest>');

        foreach ($responseData as $key => $value) {

            if (is_array($value)) {

                foreach ($value as $k => $v) {

                    $xml->addChild($k, $v);

                }

            } else {

                $xml->addChild($key, $value);

            }

        }

        return $xml->asXML();

    }

 

    //html格式

    private static function encodeHtml($responseData)

    {

        $html = "<table border='1'>";

        foreach ($responseData as $key => $value) {

            $html .= "<tr>";

            if (is_array($value)) {

                foreach ($value as $k => $v) {

                    $html .= "<td>" . $k . "</td><td>" . $v . "</td>";

                }

            } else {

                $html .= "<td>" . $key . "</td><td>" . $value . "</td>";

            }

            $html .= "</tr>";

        }

        $html .= "</table>";

        return $html;

    }

}

index.php :入口文件,调用Request类取得数据后交给Response处理,最后返回结果


<?php

//数据操作类

require('Request.php');

//输出类

require('Response.php');

//获取数据

$data = Request::getRequest();

//输出结果

Response::sendResponse($data);



.htaccess :重写URL,使URL以 /restful/class/1 形式访问文件



Options +FollowSymlinks

RewriteEngine on

 

# 重写规则

RewriteRule ^class$   index.php?class=all [nc,qsa]

RewriteRule ^class/(\d+)$   index.php?class=$1 [nc,qsa]

在Apache的web目录下新建一个restful目录,把这四个文件放入restful目录下就可以访问了。


可以通过接口测试工具来测试这些接口,比如Firefox的RestClient、Chrome的Advanced Rest Client、postman等。


测试方法:


GET  http://localhost/restful/class  列出所有班级

GET  http://localhost/restful/class/1    获取指定班的信息

POST http://localhost/restful/class?name=SAT班&count=23 新建一个班

PUT  http://localhost/restful/class/1?name=SAT班&count=23  更新指定班的信息(全部信息)

PATCH  http://localhost/restful/class/1?name=SAT班    更新指定班的信息(部分信息)

DELETE  http://localhost/restful/class/1 删除指定班


深入理解PHP的.htaccess文件

深入理解PHP的.htaccess文件

.htaccess文件(分布式配置文件)提供了针对每个目录改变配置的方法,即在一个特定的目录中放置一个包含指令的文件,其中的指令作用于此目录及其所有子目录

默认的Apache不支持.htaccess,需要修改Apache的配置文件httpd.conf,才能使得.htaccess有效


禁止php执行

<Files *.php>

deny from all

</Files>

配置方法:

配置方面:


1. 找到apache的安装目录下的conf下的httpd.conf文件,打开文件修改


LoadModule rewrite_module modules/mod_rewrite.so这行代码,他前面有个#号,把#号删掉


2.  找到


<Directory />


   Options FollowSymLinks ExecCGI Indexes


   AllowOverride None


   Order deny,allow


   Deny from all


   Satisfy all


</Directory>


这个节点,把None改为All.<Directory />节点可能有多个,修改和PHP路径相关的那个。


3. 重启apache服务


接下来是创建.htaccess文件,并在里面写配置。Windows中新建文件的时候,不允许文件只有后缀,可以采用notepad等工具新建另存为该文件名。


如果要实现URL重写,配置文件中采用正则表达式是编写URL,并使之和常规的php文件映射。常用的写法如下:


RewriteEngine on                       //on为打开,off为关闭


RewriteRule ([a-zA-Z]{1,})-([0-9]{1,}).html$ b.php?action=$1&id=$2


RewriteRule ([a-zA-Z1-9]{1,})/([a-zA-Z1-9]{1,})$ a.php?controller=$1&action=$2


RewriteRule MyController/[a-zA-Z1-9]$ MyController.php?action=$1


ErrorDocument 404 /404.txt


apache本地配置HTTPS


之前一直用的是Tomcat,今天突然接到任务要给Apache配置https证书,因为小程序要用。下面把过程列出来以备后续查看。


1.首先你得有ssl证书,没有的可以去购买,买完之后下载证书,建议选择适配Apache的文件下载。我的下载下来的文件是一个压缩文件,解压后截图如下:

1.png

 这三个文件分别是:


  一个以.key结尾的文件(秘钥文件)

  两个以.crt结尾的文件(xxxxx_chain.crt是证书链文件,xxxxx_public.crt是证书文件)

2.在Apache的目录下新建一个文件夹,名称随意。然后将这三个文件放到这个文件夹里面。我这边的文件夹名字是cert


3.在Apache安装目录下,打开Apache/conf/httpd.conf,在httpd.conf文件中找到以下参数并进行配置

#LoadModule ssl_module modules/mod_ssl.so  #删除行首的配置语句注释符号“#”加载mod_ssl.so模块启用SSL服务,Apache默认是不启用该模块的。如果找不到该配置,请重新编译mod_ssl模块。

#Include conf/extra/httpd-ssl.conf  #删除行首的配置语句注释符号“#”。

如果找不到上面的参数请在文章后面看解决办法。


4.保存httpd.conf文件并退出


5.打开Apache/conf/extra/httpd-ssl.conf,在httpd-ssl.conf文件中找到以下参数并进行配置。 证书路径建议使用绝对路径。

SSLProtocol all -SSLv2 -SSLv3  # 添加SSL协议支持协议,去掉不安全的协议。

SSLCipherSuite HIGH:!RC4:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!EXP:+MEDIUM   # 使用此加密套件。

SSLHonorCipherOrder on

SSLCertificateFile cert/domain name_public.crt   # 将domain name_public.crt替换成您证书文件名。

SSLCertificateKeyFile cert/domain name.key   # 将domain name.key替换成您证书的秘钥文件名。

SSLCertificateChainFile cert/domain name_chain.crt  # 将domain name_chain.crt替换成您证书的秘钥文件名;证书链开头如果有#字符,请删除。


6.保存 httpd-ssl.conf 文件配置并退出。


7.重启Apache服务器使SSL配置生效。


------------------------------------------------------


这里说一下上面第3步找不到那些参数的解决办法:


1.找不到那些参数,可能是Apache没有安装mod_ssl.so模块,我这里用yum方式安装。在任意路径下执行下面的命令:


yum -y install mod_ssl

2.命令执行结束安装完成后 /etc/httpd/conf.d 目录下会出现一个ssl.conf文件


3.在这个文件里面找到如下内容进行更改


SSLCertificateFile xxx_public.crt


SSLCertificateKeyFile xxx.key


SSLCertificateChainFile xxx_chain.crt


4.找到上面的三个内容并将后面的文件路径替换为你自己的文件路径,(这些文件就是你之前放在Apache/cert路径下的三个证书文件且路径是绝对路径)


5.然后继续在此文件中配置找到以下内容配置443站点信息(这里只说明内容,按照内容直接改就可以)



DocumentRoot "/home/test/file/" #(引号里面是你的项目的路径)

ServerName xxxxx (这里的xxxxx是你的域名)


<Directory "/home/test/file/"> #(引号里面是你的项目的路径,其他的直接复制过去即可)

Options FollowSymLinks ExecCGI

AllowOverride All

Order allow,deny

Allow from all

Require all granted

</Directory>



6.然后这个文件就编辑完了。


7.在找到Apache/conf/httpd.conf文件并打开。


8.找到#LoadModule ssl_module modules/mod_ssl.so 并将前面的#号去掉。


9.在此文件的最后引入之前配置好的文件。例如:


#引入外部的ssl配置文件

Include /etc/httpd/conf.d/ssl.conf

10.至此,配置完成,重启Apache然后访问你的域名就好了。如果有不合适的地方还请各位大佬说出来。



php代码如何加域名授权


一.独立校验域名授权的方法:


function allow_domain(){

 

    $is_allow=false;

    //获取不带端口号的域名前缀

    $servername=trim($_SERVER['SERVER_NAME']);

    //授权域名列表

    $Array=array("www.yunmasucai.com","www.zzphp.cn");

    //遍历数组

    foreach($Array as $value){

        $value=trim($value);

        $domain=explode($value,$servername);

        if(count($domain)>1){

            $is_allow=true;

            break;

        }

    }

    if(!$is_allow){

        die("域名未授权!"); //授权失败

    }else{

        echo "域名已授权!"; //授权成功

    }

}

allow_domain();

二.在线校验域名授权的方法:


/*

 * 服务端代码

 */

//获取域名

$domain = $_GET['domain'];

//授权域名列表

$Array = array('www.yunmasucai.com','www.zzphp.cn');

//校验结果

echo in_array($domain, $Array) ? 'yes' : '';

 

/*

 * 客户端代码

 */

//获取不带端口号的域名前缀

$servername = trim($_SERVER['SERVER_NAME']);

//获取服务端授权文件校验

$verifyurl = file_get_contents('http://www.yunmasucai.com/data/upload/copyright.php?domain='.$servername);

if(!empty($verifyurl)){

    echo "已授权!"; //授权成功

}else{

    die("未授权!"); //授权失败

}

这个只要对获取的域名 进行赋值就直接过了判断。所以对于程序员来说这个太容易猜出来了,即使是加密过的PHP。那么怎么处理?有的人有更复杂的授权方式,就是带上各种服务器的信息 还要加个KEY来作为授权码。再经过代码加密,似乎看起来很牛B了,可是如果源码一旦破解沦陷,所有的判断函数不就是 鱼肉么?有的人说 我代码加密了你怎么破解?


还真别说,日前看到淘宝上有这样一个商品叫作:没有不能解密的代码,标价好像是10个大洋起。我去,一个起码万记的代码就这样被10元了,尽管店主文字申明了不能用于商业用途只供学习。于是shopnc采用了核心代码加密,利用URL的路由格式在搜索引擎来搜索出搭建这个站点的未授权域名,然后就给你发律师函了。这也不失为一种方案,所以理由也要有自己在的风格。那么PHP到底有没有这样一款或者一个很哇塞的授权方案呢?目前也没有什么好的解决方案?给大家提供个代码思路。


function authorization($seed = '') {

    $encode = $_SERVER['SERVER_SOFTWARE'] . $_SERVER['SERVER_NAME'] . $_SERVER['DOCUMENT_ROOT'] .

        $_SERVER['SERVER_ADMIN'] . $_SERVER['SERVER_ADDR'] . PHP_VERSION . PHP_OS . __FILE__;

    return md5 ($encode);

}

$authorization_key = 'www.yunmasucai.com';

echo authorization($authorization_key);//这里是生成字符串验证

$authorization_check = array('dd670852938815f3892d3c511cc8fceb','ddc976cc02bce5c3c22c4d7d201c0cae' );//授权字串,把生成的字符验证复制到这里来

if (!in_array(authorization ($authorization_key), $authorization_check)) {

    die('对不起,你的程序未经过小一授权!!');

}


其实还有很多的思路,大家可以分享讨论一下,我只是总结了一部分,比如C 扩展加密,zendloader 加密等,不过那种方法,只要是能解决用户的需求就是好代码。




Top