C语言 c++ php mysql nginx linux lnmp lamp lanmp memcache redis 面试 笔记 ppt 设计模式 问题 远程连接

随笔 - 305  文章 - 1  评论 - 50  阅读 - 168万

php随笔小技巧

复制代码
//更改自动加载时调用的函数     
spl_autoload_register(array('Core_Fun','_class_autoload'));

//脚本执行完毕时调用
register_shutdown_function()

//获取指定下标的参数
func_get_arg($offset)

//把获取的全部参数放到一个数组里
func_get_args()
复制代码

file_put_contents设置超时时间

 

复制代码
$opt = array(
     'http'=>array(
        'method'=>"GET",
        'header'=>"Content-Type: text/html; charset=utf-8",
        'timeout'=>2
    )    
);
$context = stream_context_create($opt);
file_get_contents("http://www.baidu.com", false, $context);
复制代码

curl中的超时设置:curl_setopt($ch, CURLOPT_TIMEOUT, 3)

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.baidu.com");
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$data = curl_exec($ch);
curl_close($ch);

 fscoketopen 超时

复制代码
function request($host, $uri, $timeout = 3, $port = 80)
{
    $fp = fsockopen ( $host, 80, $errno, $errstr, $timeout );
    if (! $fp) {
        echo "$errstr ($errno)<br />\n";
        exit;
    } else {
        $data = '';
        stream_set_timeout ( $fp, $timeout ); //#
        $out = "GET {$uri} HTTP/1.1\r\n";
        $out .= "Host: {$host}\r\n";
        $out .= "Connection: Close\r\n\r\n";
        fwrite ( $fp, $out );
        while ( ! feof ( $fp ) ) {
            $data .= fgets ( $fp, 128 );
        }
        fclose ( $fp );
        return $data;
    }
    
}

echo request('www.cnblogs.com', '/siqi');
复制代码

 

 

 

抽象类的妙用:可以用来做单例模式用

 

复制代码
class man{
    public $a = 1;
    
    public function __construct()
    {
        echo 'new';
    }
    
    public function say()
    {
        echo 'saying';
    }
}

//抽象类不可以直接被实例化(巧妙的运用)
abstract class people{
    
    public $a = 123;
    
    public static function get_obj()
    {
        //这个的变量改成成员变量也是可以的
        static $obj = null;
        
        if(is_null($obj))
        {
            $obj = new man();
        }
        return $obj;
    }
}

// 只输出的一个new说明只实例化了一次
$p1 = people::get_obj();
$p2 = people::get_obj();
复制代码

 

用数组中的每个值一次去替换字符串中的自定字符

//$sql = "?,?,?,?"
//$data = array('a', 'b', 'c', 'd');
//一次替换一个问号
for($i=0;$i<$count;$i++){
$sql=preg_replace('/\?/',"'".mysql_escape_string($data[$i])."'",$sql,1);// 一次只替换一个
}

 

 

 

复制代码
/**
 * 当发生致命性错误或者exit时都会调用此函数
 * 
 */
error_reporting(0);
register_shutdown_function ( 'handleShutdown' );

function  handleShutdown (){
    $error  =  error_get_last ();
    
    // 根据错误信息,判断是否是超时了
    if ( $error  &&  strpos ( $error [ 'message' ], 'Maximum exec' )!== false ) 
    {
        echo 'handle time out';
    }
}

set_time_limit(2);

sleep(3);
复制代码

 

 

复制代码
/**
 * 获取最后一次出错信息,无论如何也能获取到
 * 
 * error_get_last set_error_handler 都不会受环境配置的影响
 * 
 */
error_reporting(0);
ini_set("display_errors", "off");


set_error_handler(function(){

    print_r(func_get_args());

});

echo $a ;
print_r(error_get_last());
复制代码

 

//$php_errormsg 获取php前一个错误信息 ,必须在 php.ini 中 track_errors = On
ini_set('track_errors', true);
echo $a;
echo $php_errormsg; //Undefined variable: a

 

复制代码
//调试

// 输出所有的函数
get_defined_functions();

//获取所定义的常量
get_defined_constants();

//获取所定义的变量
get_defined_vars();
复制代码

 

 

#对于请求外部地址curl比file_get_contents效率更高
#禁用后者php.ini中修改
allow_url_fopen = Off
#重启php-fpm

 

 

复制代码
#正则中对\的理解

$str = '<a href=\"db.house.qq\"></a>';

#双引号中可以转义的符合会被执行,输出后不在显示转义符
echo "/\\\\\"db.house.qq\\\\\"/" . "\n"; // /\\"db.house.qq\\"/ 总结:在双引号的正则中一个\需要写成 \\

#正则本身的转义符号也需要转义
var_dump(preg_match("/\\\\\"db.house.qq\\\\\"/", $str, $m));

#单引号写法,单引号中的内容不会执行
var_dump(preg_match('/\\\"db.house.qq\\\"/', $str, $m));

print_r($m);


复制代码

 

 

// ?: 匹配但不捕获 加在前面
//? 去贪婪 加在后面
// \1 反向引用
// $1 捕获
$str = 'a a';
preg_match("/(a)(?:\s+)\\1/", $str, $m); #1
echo preg_replace("/(a)(\s+)\\1/", "$1", $str); #a
print_r($m);

 

#php通过mysql取出的数据库的数据都是字符串类型

 

#关闭gpc
magic_quotes_gpc=Off
get_magic_quotes_gpc()

 

#请不要在程序里面嵌套任何PHP标签(以免多次调用PHP解析器)

 

#strtolower会在没有安装中文语言的系统中把中文转成乱码,用下面的这个函数
strtr($string, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');

 

#如果print/echo输出HTML会被Apache加上缓存头,如果不希望被缓存,则需要加上上面的输出无缓存头代码来避免
@header('Cache-Control: no-cache, must-revalidate, max-age=0');
@header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
@header('Pragma: no-cache');

 

file_get_contents() 读取文件要比 fopen/fread 快30倍,但请求外部地址很慢,请用curl替代

 

null ++ 为1, -- 仍为null  字符串只可以++,相当于最后一个字节加1, --则没效果

 

 

复制代码
/**
 * sql转义,并把输入转换成可插入的sql
 * @author root
 *
 */
class escape{

    /**
     * 内部函数,做insert操作时候的字符串过滤
     *
     * @param unknown_type $data
     * @return int or errorno
     */
    public function compile_insert_string($data)
    {
        $field_names  = '';
        $field_values = '';

        foreach ($data as $k => $v)
        {
            $field_names  .= "$k,";

            if ( is_numeric( $v ) and intval($v) == $v )
            {
                $field_values .= intval($v).",";
            }elseif ($v === null)
            {
                //兼容字段值为null的
                $field_values .= "null,";
            }else 
            {
                $field_values .= "'".$this->format_string($v)."',";
            }
        }
        //去掉最后一个,
        $field_names  = preg_replace( "/,$/" , "" , $field_names  );
        $field_values = preg_replace( "/,$/" , "" , $field_values );

        return array( 
            'FIELD_NAMES'  => $field_names,
            'FIELD_VALUES' => $field_values,
        );
    }
    
    /**
     * 格式化参数,php连接mysql的时候,可能导致SQL注入攻击,使用这个来做过滤
     *
     * @param string $str
     * @return string
     */
    public function format_string($str)
    {
        if (get_magic_quotes_gpc())
        {
            $str = stripslashes($str);
        }
        if (!is_numeric($str))
        {
            //$str = mysqli_real_escape_string($this->connection, $str);
        }
        return $str;
    }
}

$insert_arr = array("id"=>1, "name"=>"sjk");

$e = new escape();
$formated_array =  $e->compile_insert_string($arr);
$table = "card";
$insert_sql = 'INSERT INTO '.$table.' ('.$formated_array['FIELD_NAMES'].') VALUES('.$formated_array['FIELD_VALUES'].')';
复制代码

 

#注意需要带上引号
(include 'mth.php') == "a";

 

#外部参数的验证原则:对外部参数进程合法性验证,对于不符合的应该拒绝而不是使其合法

 

复制代码
spl_autoload_*类函数运用

//获取加载文件的扩展名
spl_autoload_extensions()

//获取所有注册的函数列表
spl_autoload_functions

//反注册一个自动加载函数
spl_autoload_unregister();

//注册一个函数,注意此操作会覆盖原来的 __autoload 函数
spl_autoload_register(func_name);
//某个类的某个方法
spl_autoload_register(array('AutoloadClass', 'autoload')); //autoload 为静态方法
spl_autoload_register(array($this, 'autoload')); //$this 代表一个对象
复制代码

 

复制代码
//spl_autoload_register 可重复调用,如果找到则停止搜索
function a ($c) {
    echo "a\n";
    class Bla {} // Usually "include 'path/to/file.php';"
}
function b ($c) {
    echo "b\n";
    class Bla {} // Usually "include 'path/to/file.php';"
}
spl_autoload_register('a');
spl_autoload_register('b');

$c = new Bla();
复制代码

 

复制代码
//php 1~100 单个输出 记得php.ini中设置 output_buffering = Off
echo str_repeat(' ',1024);
for($i=1;$i<100;$i++)
{
    echo $i;
    sleep(1);
//     ob_flush();
    flush();
    
}
复制代码

 

set_time_limit() 仅计算脚本自己执行的时间,调用system(),io操作,数据库查询、连接、sleep()、外部的请求(curl)等都不算在之内,并且windows下并不是这样的

//通用的测试脚本
set_time_limit(1);
$time = time();    
while(time()-$time <5)
{
    echo 'timeout';
}    

 

限制程序使用内存的大小

ini_set("memory_limit", "128M");
ini_set("memory_limit", "100K");

 

根据输出的内容设置相应的头信息,可以减少攻击

1
2
header('Content-Type:text/plain');
header('Content-Type:application/json');

  

 php中模拟不可中断睡眠

复制代码
class SleepWorkaroundForSIGALRM {
        private $time;
        function __construct($seconds) {
                $this->time = microtime(1) + $seconds;
                while ($this->time >= microtime(1)) {
                usleep(10);
                }

        }
} 
复制代码

 

数组模拟循环链表

复制代码
$a = array(0,1,2,3,4);

$i=0;
$len = count($a);

// 1
while(1)
{
    if($i==$len)
    {
        $i = 0;
    }
    
    ee($a[$i]);
    
    $i++;
    
}

// 2
while(1)
{
    $i = $i%$len;
    
    ee($a[$i]);
    
    $i++;
}

// 3
while(1)
{
    if(!next($a))
    {
        reset($a);
    }
    ee(current($a));
}

// 4
for($i=0;$i<$len;)
{
    ee($i);
    
    $i++;
    
    if($i == $len)
    {
        $i = 0;
    }
}
复制代码

 

curl 当post超过1024byte时的问题

复制代码
If you are doing a POST, and the content length is 1,025 or greater, then curl exploits a feature of http 1.1: 100 (Continue) Status.

 See http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3

 * it adds a header, "Expect: 100-continue".  
 * it then sends the request head, waits for a 100 response code, then sends the content 

 Not all web servers support this though.  Various errors are returned depending on the server.  If this happens to you, suppress the "Expect" header with this command:

<?php
 curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
?>

 See http://www.gnegg.ch/2007/02/the-return-of-except-100-continue/ 
复制代码

 

 检测url的连通性(只获取头信息,不获取返回的内容,但也必须等服务端执行完成)

复制代码
function check_url($url) { 
     $c = curl_init(); 
     curl_setopt($c, CURLOPT_URL, $url); 
     curl_setopt($c, CURLOPT_HEADER, 1); // get the header 
     curl_setopt($c, CURLOPT_NOBODY, 1); // and *only* get the header 
     curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); // get the response as a string from curl_exec(), rather than echoing it 
     curl_setopt($c, CURLOPT_FRESH_CONNECT, 1); // don't use a cached version of the url 
     if (!curl_exec($c)) { return false; } 

     $httpcode = curl_getinfo($c, CURLINFO_HTTP_CODE); 
     return ($httpcode < 400); 
 } 
复制代码

 

判断一个数组是否是关联数组

function is_assoc($arr) {
    return array_keys($arr) !== range(0, count($arr) - 1);
}

 

不同的 content-type

复制代码
设置头信息(Post请求)
1、curl_setopt ( $ch, CURLOPT_HTTPHEADER, array('Content-type:text/plain') );
file_get_contents('php://input', 'r') 获取到
$_POST                                获取不到

2、curl_setopt ( $ch, CURLOPT_HTTPHEADER, array('Content-type:application/x-www-form-urlencoded') );#默认
file_get_contents('php://input', 'r') 获取到
$_POST                                获取到

3、curl_setopt ( $ch, CURLOPT_HTTPHEADER, array('Content-type:multipart/form-data; boundary=----WebKitFormBoundarygAvW9MJkUNVmzDjY') );
file_get_contents('php://input', 'r') 获取不到
$_POST                                获取到
复制代码

 

 curl上传文件

复制代码
/**
 * 
 * 传递一个数组到CURLOPT_POSTFIELDS,cURL会把数据编码成 multipart/form-data,
 * 而然传递一个URL-encoded字符串时,数据会被编码成 application/x-www-form-urlencoded。
 * 
 */
$ch = curl_init();

$data = array('name' => 'Foo', 'file' => '@/home/user/test.png;type=xx;filename=xx');

curl_setopt($ch, CURLOPT_URL, 'http://localhost/upload.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

curl_exec($ch);
复制代码

 

curl获取头信息 (注意包括\r\n)

$response = curl_exec($ch);
 $curl_info = curl_getinfo($ch);
 curl_close($ch);
 $header_size = $curl_info['header_size'];
 $header = substr($response, 0, $header_size);
 $body = substr($response, $header_size); 

 

curl边下载边输出内容

复制代码
$ch = curl_init();
$fh = fopen('/path/to/stored/file/example_file.dat', 'w');
curl_setopt($ch, CURLOPT_FILE, $fh);
curl_setopt($ch, CURLOPT_URL, 'http://example.com/example_file.dat');
curl_exec($ch);
fflush($fh);
fclose($fh);

//must reset cURL file handle. Not doing so will cause a warning to be
//thrown and for cURL to default to output regardless
//for our example, we'll set return transfer.
curl_setopt($ch, CURLOPT_FILE, fopen('php://stdout', 'w'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_URL, 'http://example.org/index.html');
$html = curl_exec($ch); //this will now work
/**
 * 注意:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  
curl_setopt($ch, CURLOPT_FILE, $fp); 放在后面否则不起作用 ,开启后 curl_exec 不再能获取到值
 */
复制代码

 

 

 

 

 

posted on   思齐_  阅读(1094)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
< 2012年12月 >
25 26 27 28 29 30 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示