基于PHP socket + WebSocket 实现聊天室功能详解。
基于PHP socket + WebSocket 实现聊天室功能详解。
在PHP中,开发者需要考虑的东西比较多,从socket的连接、建立、绑定、监听等都需要开发者自己去操作完成,对于初学者来说,难度方面也挺大的,所以本文的思路如下:
1、socket协议的简介
2、介绍client与server之间的连接原理
3、PHP中建立socket的过程讲解
4、用一个聊天室作为实例详细讲解在PHP中如何使用socket
阅读详细 »
命令行的形式运行php
注意:在安装php时需要将php 的安装目录加到环境变量 PATH 中
(右击我的电脑->属性->高级->环境变量, 如果存在 PATH 则在原来的 PATH 中加入你的PHP安装目录, 如果不存在则新建一个 PATH)
以下是 PHP 二进制文件(即 php.exe 程序)提供的命令行模式的选项参数,您随时可以通过 PHP -h 命令来查询这些参数。
Usage: php [options] [-f] <file> [args...]
php [options] -r <code> [args...]
php [options] [-- args...]
-s Display colour syntax highlighted source.
-w Display source with stripped comments and whitespace.
-f <file> Parse <file>.
-v Version number
-c <path>|<file> Look for php.ini file in this directory
-a Run interactively
-d foo[=bar] Define INI entry foo with value 'bar'
-e Generate extended information for debugger/profiler
-z <file> Load Zend extension <file>.
-l Syntax check only (lint)
-m Show compiled in modules
-i PHP information
-r <code> Run PHP <code> without using script tags <?..?>
-h This help
args... Arguments passed to script. Use -- args when first argument
starts with - or script is read from stdin
|
CLI SAPI 模块有以下三种不同的方法来获取您要运行的 PHP 代码:
在windows环境下,尽量使用双引号, 在linux环境下则尽量使用单引号来完成。
-
让 PHP 运行指定文件。
php my_script.php php -f "my_script.php"以上两种方法(使用或不使用 -f 参数)都能够运行给定的 my_script.php 文件。您可以选择任何文件来运行,您指定的 PHP 脚本并非必须要以 .php 为扩展名,它们可以有任意的文件名和扩展名。
-
在命令行直接运行 PHP 代码。
php -r "print_r(get_defined_constants());"在使用这种方法时,请您注意外壳变量的替代及引号的使用。
注: 请仔细阅读以上范例,在运行代码时没有开始和结束的标记符!加上 -r 参数后,这些标记符是不需要的,加上它们会导致语法错误。
-
通过标准输入(stdin)提供需要运行的 PHP 代码。
以上用法给我们提供了非常强大的功能,使得我们可以如下范例所示,动态地生成 PHP 代码并通过命令行运行这些代码:
$ some_application | some_filter | php | sort -u >final_output.txt
以上三种运行代码的方法不能同时使用。
和所有的外壳应用程序一样,PHP 的二进制文件(php.exe 文件)及其运行的 PHP 脚本能够接受一系列的参数。PHP 没有限制传送给脚本程序的参数的个数(外壳程序对命令行的字符数有限制,但您通常都不会超过该限制)。传递给您脚本的参数可在全局变量 $argv 中获取。该数组中下标为零的成员为脚本的名称(当 PHP 代码来自标准输入获直接用 -r 参数以命令行方式运行时,该名称为“-”)。另外,全局变量 $argc 存有 $argv 数组中成员变量的个数(而非传送给脚本程序的参数的个数)。
只要您传送给您脚本的参数不是以 – 符号开头,您就无需过多的注意什么。向您的脚本传送以 – 开头的参数会导致错误,因为 PHP 会认为应该由它自身来处理这些参数。您可以用参数列表分隔符 — 来解决这个问题。在 PHP 解析完参数后,该符号后所有的参数将会被原样传送给您的脚本程序。
# 以下命令将不会运行 PHP 代码,而只显示 PHP 命令行模式的使用说明:
$ php -r 'var_dump($argv);' -h
Usage: php [options] [-f] <file> [args...]
[...]
# 以下命令将会把“-h”参数传送给脚本程序,PHP 不会显示命令行模式的使用说明:
$ php -r "var_dump($argv);" -- -h
array(2) {
[0]=>
string(1) "-"
[1]=>
string(2) "-h"
}
|
除此之外,我们还有另一个方法将 PHP 用于外壳脚本。您可以在写一个脚本,并在第一行以 #!/usr/bin/php 开头,在其后加上以 PHP 开始和结尾标记符包含的正常的 PHP 代码,然后为该文件设置正确的运行属性。该方法可以使得该文件能够像外壳脚本或 PERL 脚本一样被直接执行。
|
#!/usr/bin/php <?php var_dump($argv); ?> |
假设改文件名为 test 并被放置在当前目录下,我们可以做如下操作:
$ chmod 755 test
$ ./test -h -- foo
array(4) {
[0]=>
string(6) "./test"
[1]=>
string(2) "-h"
[2]=>
string(2) "--"
[3]=>
string(3) "foo"
}
|
正如您所看到的,在您向该脚本传送以 – 开头的参数时,脚本仍然能够正常运行。
PHP解决json_encode中文UNICODE转码问题(汇总)
什么是json_encode中文UNICODE转码问题?
先看下边的小列子
<?php
echo json_encode("中文");
//输出: "\u4e2d\u6587"
在使用 json_encode() 函数将变量转义成json字符串的时候,由于json_encode()仅支持中文。
json_encode()函数会将中文转成utf-8的UNICODE编码。也就是大家看到的“\uxxxx”代表一个中文汉字的形式。
如何能让PHP更好的支持中文呢?
PHP5.4开始,给 json_encode() 增加了第二个参数 JSON_UNESCAPED_UNICODE 这样就可以很好的支持中文了,中文不会在被转义成 “\uxxxx” 的形式。
<?php
echo json_encode("中文", JSON_UNESCAPED_UNICODE);
//输出: "中文"
JSON_UNESCAPED_UNICODE 常量对应的 JSON_UNESCAPED_UNICODE => 256
以上代码还可以写成
<?php
echo json_encode("中文", 256 );
//输出: "中文"
PHP5.4 为json_encode() 函数增加了 JSON_UNESCAPED_UNICODE 参数,很好的解决了中文显示的问题。他还增加了:
JSON_BIGINT_AS_STRING,
JSON_PRETTY_PRINT,
JSON_UNESCAPED_SLASHES
等选项, 如果有兴趣, 大家可以参看: json_encode
———–华丽的分割线—–PHP老版本兼容问题——–
PHP5.4 增加了 JSON_UNESCAPED_UNICODE 参数 为 变量转json字符串的中文支持提供了更好的支持。
那么老版本的PHP如何更好的支持中文呢?
总体上有2个思路
思路一:
1.在json_encode() 之前,先把中文用urlencode()函数转url编码( 中文变成%XXX的形式了)。
2.在json_encode() 之后,把url编码的中文利用urldecode()函数转成中文。
示例代码:
$array = array(
'test'=>urlencode("中文")
);
$array = json_encode($array);
echo urldecode($array);
//输出:{"test":"中文"}
思路二: 先json_encode()在解决中文UNICODE转码问题。你需要一个UNICODE转码转中文函数:
function decodeUnicode($str)
{
return preg_replace_callback('/\\\\u([0-9a-f]{4})/i',
create_function(
'$matches',
'return mb_convert_encoding(pack("H*", $matches[1]), "UTF-8", "UCS-2BE");'
),
$str);
}
有了这个函数后,你就可以这样做了 :
$arr = array('name1':"中文",'name2':'abc12');
$jsonstr = decodeUnicode(json_encode($arr));//先转json ,再处理中文UNICODE转码问题
当然,你可以将上边两步封装成一步,直接封装一个 json_encode_ex();函数。
/**
* 对变量进行 JSON 编码
* @param mixed value 待编码的 value ,除了resource 类型之外,可以为任何数据类型,该函数只能接受 UTF-8 编码的数据
* @return string 返回 value 值的 JSON 形式
*/
function json_encode_ex($value) {
if (version_compare(PHP_VERSION, '5.4.0', '<')) {
$str = json_encode($value);
$str = preg_replace_callback("#\\\u([0-9a-f]{4})#i",
function($matchs) {
return iconv('UCS-2BE', 'UTF-8', pack('H4', $matchs[1]));
},
$str);
return $str;
} else {
return json_encode($value, JSON_UNESCAPED_UNICODE);
}
}
PHP官方简体中文手册 CHM 2016最新版本
PHP官方简体中文手册 CHM 2016最新版本,改手册编译于2016年5月6日 官方终于提供了中文版手册,是国内学习PHP的新手老手的福音!这个最新的中文手册希望能给您带来帮助。

下载地址:http://pan.baidu.com/s/1dE0L7gt
备用地址:http://pan.baidu.com/s/1gf7dvov
WordPress的数据库操作类ezSQL
WordPress的数据库操作类ezSQL。
ezSQL是一个非常好用的PHP数据库操作类。著名的开源博客WordPress的数据库操作就使用了ezSQL的MySQL部分。该数据库操作类支持几乎所有主流的数据库,如:PHP-PDO, mySQL, Oracle, InterBase/FireBird, PostgreSQL, SQLite以及MS-SQL等。ezSQL具有很强的调试功能,可以快速地查看SQL代码的执行情况。使用ezSQL,可以为我们节省开发时间、简化代码并提高运行效率。
ezSQL的优点就不用多说了,它小巧、快速、简单、易用、并且开源。还有就是安全,你没想到的细节它都为你考虑了。你只需要在你的脚本开头包含相关的PHP文件,然后你就可以使用更好用的一套ezSQL函数来代替标准的PHP数据库操作函数。
下面是ezSQL中一些主要的函数:
$db->get_results — 从数据库中读取数据集。
$db->get_row — 从数据库中读取一行数据。
$db->get_col — 从数据库中读取一列指定的数据集。
$db->get_var — 从数据库的数据集中读取一个值。
$db->query — 执行一条SQL语句。
$db->debug — 打印最后执行的SQL语句及其返回的结果。
$db->vardump — 打印变量的结构及其内容。
$db->select — 选择一个新数据库。
$db->get_col_info — 获取列的信息。
$db->hide_errors — 隐藏错误。
$db->show_errors — 显示错误。
ezSQL的使用方法很简单,首先下载ezSQL源代码,然后将ez_sql_core.php文件和ez_sql_mysql.php文件(这里以mySQL为例)放到与你的脚本文件相同的目录下,然后将下面的代码添加到你的脚本文件的最前面,这样就可以正常使用ezSQL了。
<?php
// 包含ezSQL的核心文件
include_once "ez_sql_core.php";
// 包含ezSQL具体的数据库文件,这里以mySQL为例
include_once "ez_sql_mysql.php";
// 初始化数据库对象并建立数据库连接
$db = new ezSQL_mysql('db_user','db_password','db_name','db_host');
?>
下面是ezSQL中一些主要函数的应用实例,这些代码均来自于ezSQL的官方帮助文档。
实例一:
// Select multiple records from the database and print them out..
$users = $db->get_results("SELECT name, email FROM users");
foreach ( $users as $user ) {
// Access data using object syntax
echo $user->name;
echo $user->email;
}
实例二:
// Get one row from the database and print it out..
$user = $db->get_row("SELECT name,email FROM users WHERE id = 2");
echo $user->name;
echo $user->email;
实例三:
$var = $db->get_var(“SELECT count(*) FROM users”);echo $var;
// Get one variable from the database and print it out..
$var = $db->get_var("SELECT count(*) FROM users");
echo $var;
实例四:
// Insert into the database
$db->query("INSERT INTO users (id, name, email) VALUES (NULL,'justin','jv@foo.com')");
实例五:
// Update the database
$db->query("UPDATE users SET name = 'Justin' WHERE id = 2)");
实例六:
// Display last query and all associated results $db->debug();
实例七:
// Display the structure and contents of any result(s) .. or any variable
$results = $db->get_results("SELECT name, email FROM users");
$db->vardump($results);
实例八:
// Get 'one column' (based on column index) and print it out..
$names = $db->get_col("SELECT name,email FROM users",0)
foreach ( $names as $name ) {
echo $name;
}
实例九:
// Same as above ‘but quicker’
foreach ( $db->get_col("SELECT name,email FROM users",0) as $name ) {
echo $name;
}
实例十:
// Map out the full schema of any given database and print it out..
$db->select("my_database");
foreach ( $db->get_col("SHOW TABLES",0) as $table_name ) {
$db->debug();
$db->get_results("DESC $table_name");
}
$db->debug();
完整的PHP MYSQL数据库类
完整的PHP MYSQL数据库类 很多代码 值得参考
<?php
class mysql {
private $db_host; //数据库主机
private $db_user; //数据库用户名
private $db_pwd; //数据库用户名密码
private $db_database; //数据库名
private $conn; //数据库连接标识;
private $result; //执行query命令的结果资源标识
private $sql; //sql执行语句
private $row; //返回的条目数
private $coding; //数据库编码,GBK,UTF8,gb2312
private $bulletin = true; //是否开启错误记录
private $show_error = false; //测试阶段,显示所有错误,具有安全隐患,默认关闭
private $is_error = false; //发现错误是否立即终止,默认true,建议不启用,因为当有问题时用户什么也看不到是很苦恼的
/*构造函数*/
public function __construct($db_host, $db_user, $db_pwd, $db_database, $conn, $coding) {
$this->db_host = $db_host;
$this->db_user = $db_user;
$this->db_pwd = $db_pwd;
$this->db_database = $db_database;
$this->conn = $conn;
$this->coding = $coding;
$this->connect();
}
/*数据库连接*/
public function connect() {
if ($this->conn == "pconn") {
//永久链接
$this->conn = mysql_pconnect($this->db_host, $this->db_user, $this->db_pwd);
} else {
//即使链接
$this->conn = mysql_connect($this->db_host, $this->db_user, $this->db_pwd);
}
if (!mysql_select_db($this->db_database, $this->conn)) {
if ($this->show_error) {
$this->show_error("数据库不可用:", $this->db_database);
}
}
mysql_query("SET NAMES $this->coding");
}
/*数据库执行语句,可执行查询添加修改删除等任何sql语句*/
public function query($sql) {
if ($sql == "") {
$this->show_error("SQL语句错误:", "SQL查询语句为空");
}
$this->sql = $sql;
$result = mysql_query($this->sql, $this->conn);
if (!$result) {
//调试中使用,sql语句出错时会自动打印出来
if ($this->show_error) {
$this->show_error("错误SQL语句:", $this->sql);
}
} else {
$this->result = $result;
}
return $this->result;
}
/*创建添加新的数据库*/
public function create_database($database_name) {
$database = $database_name;
$sqlDatabase = 'create database ' . $database;
$this->query($sqlDatabase);
}
/*查询服务器所有数据库*/
//将系统数据库与用户数据库分开,更直观的显示?
public function show_databases() {
$this->query("show databases");
echo "现有数据库:" . $amount = $this->db_num_rows($rs);
echo "<br />";
$i = 1;
while ($row = $this->fetch_array($rs)) {
echo "$i $row[Database]";
echo "<br />";
$i++;
}
}
//以数组形式返回主机中所有数据库名
public function databases() {
$rsPtr = mysql_list_dbs($this->conn);
$i = 0;
$cnt = mysql_num_rows($rsPtr);
while ($i < $cnt) {
$rs[] = mysql_db_name($rsPtr, $i);
$i++;
}
return $rs;
}
/*查询数据库下所有的表*/
public function show_tables($database_name) {
$this->query("show tables");
echo "现有数据库:" . $amount = $this->db_num_rows($rs);
echo "<br />";
$i = 1;
while ($row = $this->fetch_array($rs)) {
$columnName = "Tables_in_" . $database_name;
echo "$i $row[$columnName]";
echo "<br />";
$i++;
}
}
/*
mysql_fetch_row() array $row[0],$row[1],$row[2]
mysql_fetch_array() array $row[0] 或 $row[id]
mysql_fetch_assoc() array 用$row->content 字段大小写敏感
mysql_fetch_object() object 用$row[id],$row[content] 字段大小写敏感
*/
/*取得结果数据*/
public function mysql_result_li() {
return mysql_result($str);
}
/*取得记录集,获取数组-索引和关联,使用$row['content'] */
public function fetch_array($resultt="") {
if($resultt<>""){
return mysql_fetch_array($resultt);
}else{
return mysql_fetch_array($this->result);
}
}
//获取关联数组,使用$row['字段名']
public function fetch_assoc() {
return mysql_fetch_assoc($this->result);
}
//获取数字索引数组,使用$row[0],$row[1],$row[2]
public function fetch_row() {
return mysql_fetch_row($this->result);
}
//获取对象数组,使用$row->content
public function fetch_Object() {
return mysql_fetch_object($this->result);
}
//简化查询select
public function findall($table) {
$this->query("SELECT * FROM $table");
}
//简化查询select
public function select($table, $columnName = "*", $condition = '', $debug = '') {
$condition = $condition ? ' Where ' . $condition : NULL;
if ($debug) {
echo "SELECT $columnName FROM $table $condition";
} else {
$this->query("SELECT $columnName FROM $table $condition");
}
}
//简化删除del
public function delete($table, $condition, $url = '') {
if ($this->query("DELETE FROM $table WHERE $condition")) {
if (!empty ($url))
$this->Get_admin_msg($url, '删除成功!');
}
}
//简化插入insert
public function insert($table, $columnName, $value, $url = '') {
if ($this->query("INSERT INTO $table ($columnName) VALUES ($value)")) {
if (!empty ($url))
$this->Get_admin_msg($url, '添加成功!');
}
}
//简化修改update
public function update($table, $mod_content, $condition, $url = '') {
//echo "UPDATE $table SET $mod_content WHERE $condition"; exit();
if ($this->query("UPDATE $table SET $mod_content WHERE $condition")) {
if (!empty ($url))
$this->Get_admin_msg($url);
}
}
/*取得上一步 INSERT 操作产生的 ID*/
public function insert_id() {
return mysql_insert_id();
}
//指向确定的一条数据记录
public function db_data_seek($id) {
if ($id > 0) {
$id = $id -1;
}
if (!@ mysql_data_seek($this->result, $id)) {
$this->show_error("SQL语句有误:", "指定的数据为空");
}
return $this->result;
}
// 根据select查询结果计算结果集条数
public function db_num_rows() {
if ($this->result == null) {
if ($this->show_error) {
$this->show_error("SQL语句错误", "暂时为空,没有任何内容!");
}
} else {
return mysql_num_rows($this->result);
}
}
// 根据insert,update,delete执行结果取得影响行数
public function db_affected_rows() {
return mysql_affected_rows();
}
//输出显示sql语句
public function show_error($message = "", $sql = "") {
if (!$sql) {
echo "<font color='red'>" . $message . "</font>";
echo "<br />";
} else {
echo "<fieldset>";
echo "<legend>错误信息提示:</legend><br />";
echo "<div style='font-size:14px; clear:both; font-family:Verdana, Arial, Helvetica, sans-serif;'>";
echo "<div style='height:20px; background:#000000; border:1px #000000 solid'>";
echo "<font color='white'>错误号:12142</font>";
echo "</div><br />";
echo "错误原因:" . mysql_error() . "<br /><br />";
echo "<div style='height:20px; background:#FF0000; border:1px #FF0000 solid'>";
echo "<font color='white'>" . $message . "</font>";
echo "</div>";
echo "<font color='red'><pre>" . $sql . "</pre></font>";
$ip = $this->getip();
if ($this->bulletin) {
$time = date("Y-m-d H:i:s");
$message = $message . "\r\n$this->sql" . "\r\n客户IP:$ip" . "\r\n时间 :$time" . "\r\n\r\n";
$server_date = date("Y-m-d");
$filename = $server_date . ".txt";
$file_path = "error/" . $filename;
$error_content = $message;
//$error_content="错误的数据库,不可以链接";
$file = "error"; //设置文件保存目录
//建立文件夹
if (!file_exists($file)) {
if (!mkdir($file, 0777)) {
//默认的 mode 是 0777,意味着最大可能的访问权
die("upload files directory does not exist and creation failed");
}
}
//建立txt日期文件
if (!file_exists($file_path)) {
//echo "建立日期文件";
fopen($file_path, "w+");
//首先要确定文件存在并且可写
if (is_writable($file_path)) {
//使用添加模式打开$filename,文件指针将会在文件的开头
if (!$handle = fopen($file_path, 'a')) {
echo "不能打开文件 $filename";
exit;
}
//将$somecontent写入到我们打开的文件中。
if (!fwrite($handle, $error_content)) {
echo "不能写入到文件 $filename";
exit;
}
//echo "文件 $filename 写入成功";
echo "——错误记录被保存!";
//关闭文件
fclose($handle);
} else {
echo "文件 $filename 不可写";
}
} else {
//首先要确定文件存在并且可写
if (is_writable($file_path)) {
//使用添加模式打开$filename,文件指针将会在文件的开头
if (!$handle = fopen($file_path, 'a')) {
echo "不能打开文件 $filename";
exit;
}
//将$somecontent写入到我们打开的文件中。
if (!fwrite($handle, $error_content)) {
echo "不能写入到文件 $filename";
exit;
}
//echo "文件 $filename 写入成功";
echo "——错误记录被保存!";
//关闭文件
fclose($handle);
} else {
echo "文件 $filename 不可写";
}
}
}
echo "<br />";
if ($this->is_error) {
exit;
}
}
echo "</div>";
echo "</fieldset>";
echo "<br />";
}
//释放结果集
public function free() {
@ mysql_free_result($this->result);
}
//数据库选择
public function select_db($db_database) {
return mysql_select_db($db_database);
}
//查询字段数量
public function num_fields($table_name) {
//return mysql_num_fields($this->result);
$this->query("select * from $table_name");
echo "<br />";
echo "字段数:" . $total = mysql_num_fields($this->result);
echo "<pre>";
for ($i = 0; $i < $total; $i++) {
print_r(mysql_fetch_field($this->result, $i));
}
echo "</pre>";
echo "<br />";
}
//取得 MySQL 服务器信息
public function mysql_server($num = '') {
switch ($num) {
case 1 :
return mysql_get_server_info(); //MySQL 服务器信息
break;
case 2 :
return mysql_get_host_info(); //取得 MySQL 主机信息
break;
case 3 :
return mysql_get_client_info(); //取得 MySQL 客户端信息
break;
case 4 :
return mysql_get_proto_info(); //取得 MySQL 协议信息
break;
default :
return mysql_get_client_info(); //默认取得mysql版本信息
}
}
//析构函数,自动关闭数据库,垃圾回收机制
public function __destruct() {
if (!empty ($this->result)) {
$this->free();
}
mysql_close($this->conn);
} //function __destruct();
/*获得客户端真实的IP地址*/
function getip() {
if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown")) {
$ip = getenv("HTTP_CLIENT_IP");
} else
if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown")) {
$ip = getenv("HTTP_X_FORWARDED_FOR");
} else
if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown")) {
$ip = getenv("REMOTE_ADDR");
} else
if (isset ($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown")) {
$ip = $_SERVER['REMOTE_ADDR'];
} else {
$ip = "unknown";
}
return ($ip);
}
function inject_check($sql_str) { //防止注入
$check = eregi('select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile', $sql_str);
if ($check) {
echo "输入非法注入内容!";
exit ();
} else {
return $sql_str;
}
}
function checkurl() { //检查来路
if (preg_replace("/https?:\/\/([^\:\/]+).*/i", "\\1", $_SERVER['HTTP_REFERER']) !== preg_replace("/([^\:]+).*/", "\\1", $_SERVER['HTTP_HOST'])) {
header("Location: http://www.dareng.com");
exit();
}
}
}
?>
php发邮件类smtp
php发邮件类smtp代码:
<?php
class smtp {
/* Public Variables */
var $smtp_port;
var $time_out;
var $host_name;
var $log_file;
var $relay_host;
var $debug;
var $auth;
var $user;
var $pass;
/* Private Variables */
var $sock;
/* Constractor */
function smtp($relay_host = "", $smtp_port = 25, $auth = false, $user, $pass) {
$this->debug = FALSE;
$this->smtp_port = $smtp_port;
$this->relay_host = $relay_host;
$this->time_out = 30; //is used in fsockopen()
//
$this->auth = $auth; //auth
$this->user = $user;
$this->pass = $pass;
//
$this->host_name = "localhost"; //is used in HELO command
$this->log_file = "";
$this->sock = FALSE;
}
/* Main Function */
function sendmail($to, $from, $subject = "", $body = "", $mailtype, $cc = "", $bcc = "", $additional_headers = "") {
$mail_from = $this->get_address($this->strip_comment($from));
$body = preg_replace("/(^|(\r\n))(\.)/", "\1.\3", $body);
$header = "MIME-Version:1.0\r\n";
if ($mailtype == "HTML") {
$header.= "Content-Type:text/html\r\n";
}
$header.= "To: " . $to . "\r\n";
if ($cc != "") {
$header.= "Cc: " . $cc . "\r\n";
}
$header.= "From: $from<" . $from . ">\r\n";
$header.= "Subject: " . $subject . "\r\n";
$header.= $additional_headers;
$header.= "Date: " . date("r") . "\r\n";
$header.= "X-Mailer:By Redhat (PHP/" . phpversion() . ")\r\n";
list($msec, $sec) = explode(" ", microtime());
$header.= "Message-ID: <" . date("YmdHis", $sec) . "." . ($msec * 1000000) . "." . $mail_from . ">\r\n";
$TO = explode(",", $this->strip_comment($to));
if ($cc != "") {
$TO = array_merge($TO, explode(",", $this->strip_comment($cc)));
}
if ($bcc != "") {
$TO = array_merge($TO, explode(",", $this->strip_comment($bcc)));
}
$sent = TRUE;
foreach ($TO as $rcpt_to) {
$rcpt_to = $this->get_address($rcpt_to);
if (!$this->smtp_sockopen($rcpt_to)) {
$this->log_write("Error: Cannot send email to " . $rcpt_to . "\n");
$sent = FALSE;
continue;
}
if ($this->smtp_send($this->host_name, $mail_from, $rcpt_to, $header, $body)) {
$this->log_write("E-mail has been sent to <" . $rcpt_to . ">\n");
} else {
$this->log_write("Error: Cannot send email to <" . $rcpt_to . ">\n");
$sent = FALSE;
}
fclose($this->sock);
$this->log_write("Disconnected from remote host\n");
}
return $sent;
}
/* Private Functions */
function smtp_send($helo, $from, $to, $header, $body = "") {
if (!$this->smtp_putcmd("HELO", $helo)) {
return $this->smtp_error("sending HELO command");
}
//auth
if ($this->auth) {
if (!$this->smtp_putcmd("AUTH LOGIN", base64_encode($this->user))) {
return $this->smtp_error("sending HELO command");
}
if (!$this->smtp_putcmd("", base64_encode($this->pass))) {
return $this->smtp_error("sending HELO command");
}
}
//
if (!$this->smtp_putcmd("MAIL", "FROM:<" . $from . ">")) {
return $this->smtp_error("sending MAIL FROM command");
}
if (!$this->smtp_putcmd("RCPT", "TO:<" . $to . ">")) {
return $this->smtp_error("sending RCPT TO command");
}
if (!$this->smtp_putcmd("DATA")) {
return $this->smtp_error("sending DATA command");
}
if (!$this->smtp_message($header, $body)) {
return $this->smtp_error("sending message");
}
if (!$this->smtp_eom()) {
return $this->smtp_error("sending <CR><LF>.<CR><LF> [EOM]");
}
if (!$this->smtp_putcmd("QUIT")) {
return $this->smtp_error("sending QUIT command");
}
return TRUE;
}
function smtp_sockopen($address) {
if ($this->relay_host == "") {
return $this->smtp_sockopen_mx($address);
} else {
return $this->smtp_sockopen_relay();
}
}
function smtp_sockopen_relay() {
$this->log_write("Trying to " . $this->relay_host . ":" . $this->smtp_port . "\n");
$this->sock = @fsockopen($this->relay_host, $this->smtp_port, $errno, $errstr, $this->time_out);
if (!($this->sock && $this->smtp_ok())) {
$this->log_write("Error: Cannot connenct to relay host " . $this->relay_host . "\n");
$this->log_write("Error: " . $errstr . " (" . $errno . ")\n");
return FALSE;
}
$this->log_write("Connected to relay host " . $this->relay_host . "\n");
return TRUE;;
}
function smtp_sockopen_mx($address) {
$domain = preg_replace("/^.+@([^@]+)$/", "\1", $address);
if (!@getmxrr($domain, $MXHOSTS)) {
$this->log_write("Error: Cannot resolve MX \"" . $domain . "\"\n");
return FALSE;
}
//专注与php学习 http://www.daixiaorui.com 欢迎您的访问
foreach ($MXHOSTS as $host) {
$this->log_write("Trying to " . $host . ":" . $this->smtp_port . "\n");
$this->sock = @fsockopen($host, $this->smtp_port, $errno, $errstr, $this->time_out);
if (!($this->sock && $this->smtp_ok())) {
$this->log_write("Warning: Cannot connect to mx host " . $host . "\n");
$this->log_write("Error: " . $errstr . " (" . $errno . ")\n");
continue;
}
$this->log_write("Connected to mx host " . $host . "\n");
return TRUE;
}
$this->log_write("Error: Cannot connect to any mx hosts (" . implode(", ", $MXHOSTS) . ")\n");
return FALSE;
}
function smtp_message($header, $body) {
fputs($this->sock, $header . "\r\n" . $body);
$this->smtp_debug("> " . str_replace("\r\n", "\n" . "> ", $header . "\n> " . $body . "\n> "));
return TRUE;
}
function smtp_eom() {
fputs($this->sock, "\r\n.\r\n");
$this->smtp_debug(". [EOM]\n");
return $this->smtp_ok();
}
function smtp_ok() {
$response = str_replace("\r\n", "", fgets($this->sock, 512));
$this->smtp_debug($response . "\n");
if (!preg_match("/^[23]/", $response)) {
fputs($this->sock, "QUIT\r\n");
fgets($this->sock, 512);
$this->log_write("Error: Remote host returned \"" . $response . "\"\n");
return FALSE;
}
return TRUE;
}
function smtp_putcmd($cmd, $arg = "") {
if ($arg != "") {
if ($cmd == "") $cmd = $arg;
else $cmd = $cmd . " " . $arg;
}
fputs($this->sock, $cmd . "\r\n");
$this->smtp_debug("> " . $cmd . "\n");
return $this->smtp_ok();
}
function smtp_error($string) {
$this->log_write("Error: Error occurred while " . $string . ".\n");
return FALSE;
}
function log_write($message) {
$this->smtp_debug($message);
if ($this->log_file == "") {
return TRUE;
}
$message = date("M d H:i:s ") . get_current_user() . "[" . getmypid() . "]: " . $message;
if (!@file_exists($this->log_file) || !($fp = @fopen($this->log_file, "a"))) {
$this->smtp_debug("Warning: Cannot open log file \"" . $this->log_file . "\"\n");
return FALSE;;
}
flock($fp, LOCK_EX);
fputs($fp, $message);
fclose($fp);
return TRUE;
}
function strip_comment($address) {
$comment = "/\([^()]*\)/";
while (preg_match($comment, $address)) {
$address = preg_replace($comment, "", $address);
}
return $address;
}
function get_address($address) {
$address = preg_replace("/([ \t\r\n])+/", "", $address);
$address = preg_replace("/^.*<(.+)>.*$/", "\1", $address);
return $address;
}
function smtp_debug($message) {
if ($this->debug) {
echo $message;
}
}
}
/*----end---*/
调用:
include_once "Inc/smtp.class.php"; //******************** 配置信息 ******************************** $smtpserver = "smtp.qq.com";//SMTP服务器 $smtpserverport =25;//SMTP服务器端口 $smtpusermail = "718222265@qq.com";//SMTP服务器的用户邮箱 $smtpuser = "718222265";//SMTP服务器的用户帐号 $smtppass = "****";//SMTP服务器的用户密码 $smtpemailto = '378398666@qq.com';//发送给谁 $mailtitle = "邮件主题";//邮件主题 $mailcontent = "邮件内容";//邮件内容 $mailtype = "HTML";//邮件格式(HTML/TXT),TXT为文本邮件 //************************ 配置信息 **************************** $smtp = new smtp($smtpserver,$smtpserverport,true,$smtpuser,$smtppass);//这里面的一个true是表示使用身份验证,否则不使用身份验证. $smtp->debug = false;//是否显示发送的调试信息 $state = $smtp->sendmail($smtpemailto, $smtpusermail, $mailtitle, $mailcontent, $mailtype);
利用Data URL(data:image/jpg;base64,)加速网页加载的方法
利用Data URL(data:image/jpg;base64,)base64形式存储图片,将小图片生成数据流形式
先来看下下边这段代码:
<img src=”data:image/gif;base64,R0lGODlhJQAlAJECAL3L2AYrTv///wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFCgACACwAAAAA
JQAlAAACi5SPqcvtDyGYIFpF690i8xUw3qJBwUlSadmcLqYmGQu6KDIeM13beGzYWWy3DlB4IYaM
k+Dso2RWkFCfLPcRvFbZxFLUDTt21BW56TyjRep1e20+i+eYMR145W2eefj+6VFmgTQi+ECVY8iG
xcg35phGo/iDFwlTyXWphwlm1imGRdcnuqhHeop6UAAAIfkEBQoAAgAsEAACAAQACwAAAgWMj6nL
XAAh+QQFCgACACwVAAUACgALAAACFZQvgRi92dyJcVJlLobUdi8x4bIhBQAh+QQFCgACACwXABEA
DAADAAACBYyPqcsFACH5BAUKAAIALBUAFQAKAAsAAAITlGKZwWoMHYxqtmplxlNT7ixGAQAh+QQF
CgACACwQABgABAALAAACBYyPqctcACH5BAUKAAIALAUAFQAKAAsAAAIVlC+BGL3Z3IlxUmUuhtR2
LzHhsiEFACH5BAUKAAIALAEAEQAMAAMAAAIFjI+pywUAIfkEBQoAAgAsBQAFAAoACwAAAhOUYJnA
agwdjGq2amXGU1PuLEYBACH5BAUKAAIALBAAAgAEAAsAAAIFhI+py1wAIfkEBQoAAgAsFQAFAAoA
CwAAAhWUL4AIvdnciXFSZS6G1HYvMeGyIQUAIfkEBQoAAgAsFwARAAwAAwAAAgWEj6nLBQAh+QQF
CgACACwVABUACgALAAACE5RgmcBqDB2MarZqZcZTU+4sRgEAIfkEBQoAAgAsEAAYAAQACwAAAgWE
j6nLXAAh+QQFCgACACwFABUACgALAAACFZQvgAi92dyJcVJlLobUdi8x4bIhBQAh+QQFCgACACwB
ABEADAADAAACBYSPqcsFADs=
“>
其实“data:image/gif;base64,R0lGODlhJ……” 就是一张图片的Data URL,就是利用base64编码把图片数据翻译成标准ASCII字符。
等同于:
<img src=”http://www.lrxin.com/images/loading.gif”>
显示结果:
Data URL它现将图片转换成base64编码,以文本的形象随着文件加载。
再由浏览器在本地直接绘制图片,不是从服务器加载,所以节省了HTTP连接,起到加速网页的作用。
语法:
data:image/jpg; 声明数据协议及类型名称
base64, 编码形式为base64
/9j/4AAQSkZ…… base64编码结果
最后附上Data URL的生成方法(PHP):
<?php
//php读取和保存base64编码的图片内容
header('Content-type:text/html;charset=utf-8');
//读取图片文件,转换成base64编码格式
//$image_file = './loading.gif';
$image_file = 'http://www.lrxin.com/images/loading.gif';
$image_info = getimagesize($image_file);
$base64_image_content = "data:{$image_info['mime']};base64," . chunk_split(base64_encode(file_get_contents($image_file)));
?>
<img src="<?php echo $base64_image_content;?>" />
需要注意:本方法适合于小图片,大图片就不要考虑了,另外IE8以下浏览器不支持这种方法。
用这种方法会加重客户端的CPU和内存负担,总之有利有弊。
IE8 之前的浏览器不支持 Data URL
在线生成工具:
http://www.greywyvern.com/code/php/binary2base64
http://www.kawa.net/works/js/data-scheme/base64-e.html
简单的说,data类型的Url大致有下面几种形式。
data:,<文本数据>
data:text/plain,<文本数据>
data:text/html,<HTML代码>
data:text/html;base64,<base64编码的HTML代码>
data:text/plain;charset=UTF-8;base64,<base64编码的HTML代码>
data:text/css,<CSS代码>
data:text/css;base64,<base64编码的CSS代码>
data:text/javascript,<Javascript代码>
data:text/javascript;base64,<base64编码的Javascript代码>
data:image/gif;base64,<base64编码的gif图片数据>
data:image/png;base64,<base64编码的png图片数据>
data:image/jpeg;base64,<base64编码的jpeg图片数据>
data:image/x-icon;base64,<base64编码的icon图片数据>
php读取和保存base64编码的图片内容
<?php
//php读取和保存base64编码的图片内容
header('Content-type:text/html;charset=utf-8');
//读取图片文件,转换成base64编码格式
//$image_file = './loading.gif';
$image_file = 'http://www.lrxin.com/images/loading.gif';
$image_info = getimagesize($image_file);
$base64_image_content = "data:{$image_info['mime']};base64," . chunk_split(base64_encode(file_get_contents($image_file)));
//保存base64字符串为图片
//匹配出图片的格式
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){
$type = $result[2];
$new_file = "./test.{$type}";
if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))){
echo '新文件保存成功:', $new_file ,'<br/>';
}
}
?>
<img src="<?php echo $base64_image_content;?>" />
<br/>
<textarea style="width:80%; min-height:300px;"><?php echo $base64_image_content;?></textarea>
php 程序中 改变session存储路径
$sessSavePath = dirname(__FILE__).”/../cache/sessions/”;
if(is_writeable($sessSavePath) && is_readable($sessSavePath))
{
session_save_path($sessSavePath);//重点 改变session存储路径
}