zoukankan      html  css  js  c++  java
  • PHP开发笔记

    PHP开发笔记

    JSON数据的解析

    $json_data = isset($_GET['json_data']) ? $_GET['json_data'] : null;
    $json_data=str_replace("",'',$json_data);

    从前台接收到的json字符串,在json_decode的时候需要先将多余的反斜线字符处理掉,才能正确转换成对象或数组。

    JQuery支持的数组去重方法

    var yearArray = new Array(2009, 2009, 2010, 2010, 2009, 2010);
    $.unique(yearArray);
    返回 2009, 2010, 2009, 2010

    php字符串替换

    php字符串与变量的混合时,可以使用双引号,内部嵌套php变量。从而省去以.为分割的书写方式。

    $sql = "UPDATE ".TABLE_MOBILE_APP_DEVICES."
    SET app_name='{$req_client}',app_version='{$req_cv}',device_os='{$device_os}'

    比较适合长字符串的sql拼接。

    关于全局变量

    PHP 中全局变量在函数中使用时必须声明为 global
    且使用时若对其进行修改,则影响全局变量的值。
    也可以使用超全局变量$GLOBALS['var']来访问。
    要深入理解函数的作用范围

    PHP 中的许多预定义变量都是“超全局的”,这意味着它们在一个脚本的全部作用域中都可用。在函数或方法中无需执行 global $variable; 就可以访问它们。

    这些超全局变量是:

    $GLOBALS $_SERVER $_GET $_POST $_FILES $_COOKIE $_SESSION $_REQUEST $_ENV

    JS获取随机数

    function RandNum(n){
    var rnd="";
    for(var i=0;i<n;i++)
    rnd+=Math.floor(Math.random()*10);
    return rnd;
    }
    

    字符串的输出

    echo <<< EOF
    this is a text;
    
    输出的html大段代码。。
    
    EOF;
    

    要求起始标记和结束标记要相同。

    关于双引号和单引号的问题:

    双引号有变量解析功能!

    PHP中尽量用单引号,HTML代码全部用双引号

    在包含变量的时候,用双引号可以简化操作

    复杂的情况下用大括号包起来

    几个 PHP 的“魔术常量”

    FILE 文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。自 PHP 4.0.2 起,FILE 总是包含一个绝对路径(如果是符号连接,则是解析后的绝对路径),而在此之前的版本有时会包含一个相对路径。
    E:yuloreCodesrc_portaladminmytest.php

    DIR 文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。它等价于 dirname(FILE)。除非是根目录,否则目录中名不包括末尾的斜杠。(PHP 5.3.0中新增)
    E:yuloreCodesrc_portaladmin

    JS Ajax返回数据字符串提前转换

    if (typeof data === 'string') {
    data = JSON.parse(data);
    }

    第三方服务的异步调用

    (小米外卖)对于和第三方的接口调用,只要我们自己的服务没有出现异常或错误,返回给用户的信息应该均为成功。推第三方改为“异步调用”,即使有个别订单出现问题,可以通过人为干预或者后台运维解决。不应该因为比较小的第三方服务不稳定而拖垮我们的系统。否则严重影响用户体验。

    MySql分页的简单实现

    select * from table limit (pagenum*pagesize-pagesize),pagesize
    
    static function getPushList($pagesize, $pagenum, $status, $begintime, $endtime) {
            global $db_mysql;
            $sql_select = "SELECT p.user_id,p.template_id,p.status,ud.mobile_system,p.add_time,a.owner,a.id as apikeyid ,p.title,p.content,ua.mobile,case when ud.client_type='Getui' then '个推' end as client_type ";
            $sql_count = 'SELECT count(*) ';
            $sql = "FROM push_info p left join user_device ud on p.user_id=ud.user_id
                    left join yulore.dict_user_accounts ua on p.user_id=ua.id
                    left join yulore.admin_apikey a on a.id=ua.apikeyid  where 1=1 ";
    
            if ($status !== 'all') {
                $sql .= " and p.status='$status' ";
            }
            if (!empty($begintime)) {
                $sql .= " and p.add_time>='$begintime' ";
            }
            if (!empty($endtime)) {
                $endtime = date("Y-m-d", strtotime($endtime . " +1 day"));
                $sql .= " and p.add_time<='$endtime' ";
            }
            $sql .= ' order by p.add_time desc';
    
    
            $page = " limit " . ($pagenum * $pagesize - $pagesize) . "," . $pagesize;
    
            $sql_query = $sql_select . $sql . $page;
            //var_dump($sql_query);
            $stmt = $db_mysql->query($sql_query);
            $data = $stmt->fetchAll();
            $rs = $db_mysql->query($sql_count . $sql);
            $count = $rs->fetchAll();
            return array(
                'data' => $data,
                'max_count' => (int)$count[0][0],
            );
        }
    

    跨域的问题

    对外提供js接口的时候要考虑是否在同一个域里,或者返回jsonp的结构。

    数据传输和提交的数据量不同有不同的解决方案

    页面间数据传输要考虑数据量的大小,数据量超过一定程度的时候就不应该使用cookie了。
    可以使用html5的storage存储。
    对于大数据量ajax调用的时候不应该使用get方式,否则会出现连接字符串超长的情况。
    后台php接收的时候也需要做相应的调整。

    在HTML5中,本地存储是一个window的属性,包括localStorage和sessionStorage,从名字应该可以很清楚的辨认二者的区别,前者是一直存在本地的,后者只是伴随着session,

    窗口一旦关闭就没了(刷新和后退是存在的)。二者用法完全相同,这里以localStorage为例。

    if(window.localStorage){
    alert('This browser supports localStorage');
    }else{
    alert('This browser does NOT support localStorage');
    }
    
    localStorage.a = 3;//设置a为"3"
    localStorage["a"] = "sfsf";//设置a为"sfsf",覆盖上面的值
    localStorage.setItem("b","isaac");//设置b为"isaac"
    var a1 = localStorage["a"];//获取a的值
    var a2 = localStorage.a;//获取a的值
    var b = localStorage.getItem("b");//获取b的值
    localStorage.removeItem("c");//清除c的值
    

    任何格式存储的时候都会被自动转为字符串,所以读取的时候,需要自己进行类型的转换。

    CSS控制数据长度溢出

    text-overflow: ellipsis;(省略号,或者自定义符号)

    php服务器错误信息的显示

    在php.ini中需要打开出错开关:display_errors:On

    其次,如果在生产环境中,不能打开这种开关的情况下,也可以通过编程的形式来临时打开这个开关(但是有局限性)

    需要执行这样的设置:

    ini_set('display_errors', '1');

    前端调试,使用Fiddler调试生产环境JS

    参考:http://www.aliued.cn/2010/04/25/use-fiddler-to-improve-efficiency-of-front-development-example.html

    http://www.open-open.com/lib/view/open1375954572906.html

    生产环境的log日志级别要分清

    一般的记成info,debug,真正严重的才记成error

    controller里尽量只做简单的事情

    多线程神马的不要在controller中做。

    ajax相关:

    调用时要考虑跨域的问题。
    ajax调用时会自动携带cookie信息(fiddler中可以查看到)

    HTML5页面规范

    文件头要规范书写:

    图片延迟加载及出错替换机制

    延迟加载:参考jquery的lazyload插件

    实际使用的:滚动加载插件。参考地址:

    http://www.zhangxinxu.com/wordpress/2010/11/jquery页面图片等元素滚动动态加载实现/

    使用步骤:

    1.引用jquery,js

    2.img标签增加默认图片和实际图片的属性:

    3.调用方法: $(".scrollLoading").scrollLoading();

    出错替换机制:

    多Ajax请求异步顺序出错调试

    多个ajax请求有时候后者的请求数据需要前者的支持,因此可能会出现返回的时间和代码书写的顺序不一致的情况。典型的情况是,反复刷新页面多次,偶尔会有bug的发生,可以利用firebug的console.log(number)的方法把ajax回调函数分别按顺序log下来,看执行时候的输出情况,便可以发现这个问题,从而解决问题。

    解决方案:在controller中把多个请求合并成一个返回给页面。

    mysql 插入更新语法

    insert语句后加
    ON DUPLICATE KEY UPDATE + 列名=新值,列名=新值
    使用场景:
    这个语法和适合用在需要 判断记录是否存在,不存在则插入存在则更新的场景.
    往有唯一键表中插入数据时,如果不存在该记录则插入,存在则更新已存在的记录。
    省去了使用ifelse来判断是否有值的情况,但是性能会稍差一些
    示例
    INSERT INTO admin_tel_check_config VALUES('test_a','test','http://www.baidu.com','new',NOW())
    ON DUPLICATE KEY UPDATE check_id='test_b',check_desp='test1',api='abc',STATUS='old',date_added=NOW()

    mysql文档:http://dev.mysql.com/doc/refman/5.1/zh/sql-syntax.html#insert

    isset/empty区别

    empty

    如果 变量 是非空或非零的值,则 empty() 返回 FALSE。换句话说,""、0、"0"、NULL、FALSE、array()、var $var、未定义; 以及没有任何属性的对象都将被认为是空的,如果 var 为空,则返回 TRUE。

    isset
    如果 变量 存在(非NULL)则返回 TRUE,否则返回 FALSE(包括未定义)。变量值设置为:null,返回也是false;unset一个变量后,变量被取消了。注意,isset对于NULL值变量,特殊处理。
    is_null
    检测传入值【值,变量,表达式】是否是null,只有一个变量定义了,且它的值是null,它才返回TRUE . 其它都返回 FALSE 【未定义变量传入后会出错!】.

    PHP导出CSV

    function export_csv($filename, $data)
    {
    header("Content-type:text/csv");
    header("Content-Disposition:attachment;filename=" . $filename);
    header('Cache-Control:must-revalidate,post-check=0,pre-check=0');
    header('Expires:0');
    header('Pragma:public');
    $data = iconv('utf-8', 'gb2312', $data);
    echo $data;
    }

    生成html绑定

    对于生成的html绑定事件,需要这样
    参考:
    http://www.cnblogs.com/coffeedeveloper/archive/2013/04/19/3029922.html

    //操作事件绑定
    $('#dataContent').on('change', '.ddl_error_type', function () {
    var val = $(this).val();
    //alert(val);
    if (val == 'others') {
    $(this).parent().find(".txt_desp").show();
    $(this).parent().find(".btn_submit").show();
    }
    else if (val == 'none') {
    $(this).parent().find(".txt_desp").hide();
    $(this).parent().find(".btn_submit").hide();
    } else {
    $(this).parent().find(".txt_desp").hide();
    $(this).parent().find(".btn_submit").show();
    }
    });
    

    条件sql

    select c.condition_id,city_name,category_name,real_count,error_count,if ((select condition_id from admin_tel_check_condition_user WHERE condition_id=tb.condition_id) IS NULL,'false','true') as test_flag from admin_tel_check_condition c left join (select condition_id,count(condition_id)as error_count from admin_tel_check_result where error_type!='none' group by condition_id ) tb
    on tb.condition_id=c.condition_id 
    where c.check_id='test_20140611v1' order by city
    

    设置table从0开始自增

    alter table tablename auto_increment=0

    PHP命名空间

    require_once('regulation.class.php');
    require_once('test.class.php');

    use ReguRegulation;
    use OtherRegulation as Regulation1;

    $t=new Regulation();
    $t->test();
    //Regu test function

    $s=new Regulation1();
    $s->test();
    //Other test function

    对象转数组(深层,快速)

    $array = json_decode(json_encode($nested_object), true);

    Mysql返回影响的行数

    mysql_select_db("mydb");
    mysql_query("DELETE FROM mytable WHERE id < 5");
    $rc = mysql_affected_rows();
    echo "Records deleted: " . $rc;

    PHP字符串拆分,连接函数

    $id_arr = explode(",", $shopIds);//根据逗号分隔成数组
    $id_str = implode("-", $id_arr);//数组连接成字符串

    JQuery下拉菜单绑定选中项。

    通用,兼容,简单的方法:
    $("#select_id").val('选中项的值');

    JS写入cookie

    var date=new Date();
    var expiresDays=10;
    date.setTime(date.getTime()+expiresDays243600*1000);
    document.cookie="auth_id=ede87c9a1d083f557acb02f1a3b862036263938f2f6dc7838252ddc022d9ed06; path=/;domain=.dianhua.cn;expires="+date.toGMTString();

    PHP预处理SQL防止注入(PDO方式)

    define("PDO_DSN", "mysql:dbname={$dbname};host={$host}");
    define("PDO_USER", $user);
    define("PDO_PASS", $pwd);
    
    $this->db = new PDO(PDO_DSN, PDO_USER, PDO_PASS);
    
    try {
    $sql = "INSERT INTO ".self::TABLE_CLIENTS." (appname, client_secret, redirect_uri) VALUES (:appname, :client_secret, :redirect_uri)";
    $stmt = $this->db->prepare($sql);
    $stmt->bindParam(":appname", $appname, PDO::PARAM_STR);
    $stmt->bindParam(":client_secret", $client_secret, PDO::PARAM_STR);
    $stmt->bindParam(":redirect_uri", $redirect_uri, PDO::PARAM_STR);
    $stmt->execute();
    } catch (PDOException $e) {
    $this->handleException($e);
    }
    
    $uid = '%|' . $uid;
    $db = new PDO("mysql:dbname={$dbname};host={$host}", $user, $pwd);
    try {
    $sql = "select id from dict_user_accounts where apikeyid =:apikeyid and account like :uid ";
    $stmt = $db->prepare($sql);
    $stmt->bindParam(":apikeyid", $apikeyid, PDO::PARAM_INT);
    $stmt->bindParam(":uid", $uid, PDO::PARAM_STR);
    $stmt->execute();
    $result = $stmt->fetchALL();
    } catch (PDOException $e) {
    die('{"status":"202","msg":"Invalid Request"}');
    }
    

    PHPStorm调试配置

    [XDebug] 
    ; Only Zend OR (!) XDebug 
    zend_extension="D:xamppphpextphp_xdebug-2.2.5-5.5-vc11.dll"
    xdebug.auto_trace=On
    xdebug.collect_params=On
    xdebug.collect_return=On
    xdebug.trace_output_dir="d:/xampp/php/debuginfo"
    xdebug.profiler_enable=On
    xdebug.profiler_output_dir="d:/xampp/php/debuginfo"
    xdebug.idekey=PhpStorm
    xdebug.remote_enable=on
    xdebug.remote_host=api.dev.dianhua.cn
    xdebug.remote_port=9000
    xdebug.remote_handler=dbgp
    

    php生成get参数方法

    http_build_query($data);

    php 重定向(无回退跳转)

    header("HTTP/1.1 301 Moved Permanently");
    header("Location:$url");
    
    或者使用iframe
    <iframe style="margin: 0; padding: 0" width="100%" height="100%" frameBorder="no" src="<?php echo $url;?>" target="_top">
    </iframe>
    可以实现浏览器不记住跳转页
    
    去掉input控件的历史输入
    autocomplete="off"
    可用于input控件或者form表单
    <input AUTOCOMPLETE ="off">
    <form action="./list.php" method="get" autocomplete="off">
    

    php数据库插入json等有反斜杠的字符时,需要进行转义(参数转义)

    可用mysql_real_escape_string,addslashes(good) 函数

    switch条件语句或的运用

    switch($val){
    case 'test1':
    case 'test2':
    echo 333333;
    break;
    case 'test5':
    echo 55555;
    break;
    default:
    echo '0000';
    break;
    }
    

    JS检测数据是否是JSON

    if (typeof data === 'string') {
    data = JSON.parse(data);
    }

    php打印url

    echo '
    page url:'.$_SERVER["REQUEST_URI"];
    echo '
    http://'.$_SERVER['SERVER_NAME'].':'.$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
    echo '
    http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
    echo '

    ';
    print_r($_SERVER);
    echo '
    ';

    PHP时间处理,转换&比较

    //原生方法进行日期比较
    //mysql:SELECT FROM_UNIXTIME(1422522566), UNIX_TIMESTAMP('2015-01-29 17:09:26')
    $exp_time_raw=strtotime('2015-01-29 16:38:01');
    echoFormat('$exp_time_raw unixtime:' . $exp_time_raw);

    $time= date('Y-m-d H:i:s',$exp_time_raw);
    var_dump($time);
    使用时间戳进行大小判断!

    register_shutdown_function

    函数可实现当程序执行完成后执行的函数,其功能为可实现程序执行完成的后续操作
    register_shutdown_function('api::fatal_error');
    可用于错误处理。

    //捕获语法错误
    public static  function fatal_error() {
        if ($e = error_get_last()) {
            switch($e['type']){
              case E_ERROR:
              case E_PARSE:
              case E_CORE_ERROR:
              case E_COMPILE_ERROR:
              case E_USER_ERROR:
                self::_server_error($e['message'].' '.$e['file'].' '.$e['line']);
                break;
            }
        }
    }
    

    不同系统的路径分隔符

    define('SYSTEM_PATH',DIR.DIRECTORY_SEPARATOR);
    include SYSTEM_PATH.'inc/init.php';

    记住登录状态的实现

    1.生成一个随机的,唯一的字符串(可通过userid生成)token,保存在服务端(数据库/缓存),并与当前用户绑定。
    2.将这个token写入cookie,并设置一个过期时间(7天)
    3.用户登录时,拿着用户id和cookie中的token去服务端验证,比对。相等则认为是合法用户。
    4.比对成功后,服务端和客户端cookie同时做刷新操作(重新生成一个新的token)

    PHP定时任务需要注意的

    1.进行try catch异常捕获
    try{}
    catch (Exception $e) {
    $e->getCode() . ' message:' . $e->getMessage() . ' line:' . $e->getLine() . ' trace:' . $e->getTraceAsString());
    }
    2.设置脚本的执行时间为无限制:set_time_limit(0);
    3.引用文件使用绝对路径,即用__DIR__.'/../'方式
    4.考虑变量的回收效率,防止长时间运行占用过多内存。可以将程序模块化,在function里执行。

    json_encode扩展

    //json_encode扩展,增加php低版本中文乱码的问题
    function json_encode_extension($arr) {
     if (defined('JSON_UNESCAPED_UNICODE')) {
     return json_encode($arr, JSON_UNESCAPED_UNICODE);
     }
     return urldecode(json_encode(urlencode_arr($arr)));
    }
    
    //json_encode扩展
    function urlencode_arr($arr) {
     if (empty($arr)) {
     return null;
     }
     $result_arr = array();
     foreach ($arr as $k => $v) {
     if (is_array($v)) {
     $result_arr[$k] = urlencode_arr($v);
     } else {
     $result_arr[$k] = urlencode($v);
     }
     }
     return ($result_arr);
    }
    

    CURL设置超时时间及判断

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 6);//低版本curl不支持毫秒级超时
    if (!empty($data)) {
     curl_setopt($ch, CURLOPT_POST, 1);
     $postStr = http_build_query($data);
     curl_setopt($ch, CURLOPT_POSTFIELDS, $postStr);
    }
    if (!empty($headers)) {
     curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }
    $output = curl_exec($ch);
    // log curl error.
    if(curl_errno($ch)){
     $error_num=curl_errno($ch);
     if($error_num==28){
     $logger->error('curl post timeout! url:'.$url,$data);
     }else{
     $logger->error('curl post error:'.curl_errno($ch).' url:'.$url,$data);
     }
    }
    curl_close($ch);
    

    PHP获取毫秒时间戳

    function getMsecTime(){
    $time = explode ( " ", microtime () );
    $time = $time [1] . ($time [0] * 1000);
    $time2 = explode ( ".", $time );
    $time = $time2 [0];
    return $time;
    }

    对象序列化和反序列化

    方便把php对象或数组转换成字符串存储
    $test_arr=array('name'=>'wj','value'=>111);
    $re= serialize($test_arr);
    var_dump($re);
    var_dump(unserialize($re));

    //result:
    string 'a:2:{s:4:"name";s:2:"wj";s:5:"value";i:111;}' (length=44)

    array (size=2)
    'name' => string 'wj' (length=2)
    'value' => int 111

    PHP异常处理回调函数及页面完成回调函数

    set_exception_handler为出现异常的回调函数
    register_shutdown_function为页面退出前执行的回调函数
    使用这两个函数可以用于框架中集中处理错误及业务带来帮助

    function catch_exception_callback($e){
     echo 'catch exception<br>';
     echo $e->__toString();
    }
    
    function shutdown_callback(){
     echo '<br>begin shutdown<br>';
    }
    
    set_exception_handler('catch_exception_callback');
    register_shutdown_function('shutdown_callback');
    throw new Exception('errorR',101);
    die();
    

    php禁用页面缓存

    header('Cache-Control: max-age=0');
    header("Cache-Control: no-cache, must-revalidate"); //HTTP 1.1
    header("Pragma: no-cache");//http 1.0

    获取当前调用的信息

    debug_backtrace();

    类的方法重载

    在对象中调用一个不可访问方法时,__call() 会被调用。
    用静态方式中调用一个不可访问方法时,__callStatic() 会被调用。/** PHP 5.3.0之后版本 */
    可用于类中多个方法功能类似的单一入口,在call方法中进行判断即可,防止复制多个方法。

    php设置url中某参数

    function url_set_value($url, $key, $value) {
    $a = explode('?', $url);
    $url_f = $a[0];
    $query = $a[1];
    parse_str($query, $arr);
    $arr[$key] = $value;
    return $url_f . '?' . http_build_query($arr);
    }
    $new url=url_set_value(HOST_NAME . $_SERVER['REQUEST_URI'], 'page', '2');

    php自带验证/过滤函数

    $url = filter_var(trim($_GET['url']), FILTER_VALIDATE_URL);
    if(!$url){
    throw new Exception('跳转URL格式错误');
    }
    类似的Email验证,IP验证FILTER_VALIDATE_EMAIL,FILTER_VALIDATE_IP

    php字符串查找

    $pos = strrpos($mystring, "b");
    if ($pos === false) { // 注意: 三个等号
    // 未发现...
    }

    ========
    update 2015-04-22

  • 相关阅读:
    Resharper的使用
    SQL Server 占用CPU较高的解决方法
    014 FPGA千兆网UDP通信
    012 PCIe总线的基础知识
    008 PCI设备BAR空间的初始化
    016 基于FPGA的网口通信实例设计【转载】
    015 FPGA千兆网TCP通信【转载】
    006 PCI总线的桥与配置(一)
    004 PCI Express体系结构(四)
    007 PCI总线的桥与配置(二)
  • 原文地址:https://www.cnblogs.com/dannywang/p/4448045.html
Copyright © 2011-2022 走看看