career-tips | 踩坑路

a little tips in my code career | 碼碼踩過的那些坑2015-2016php

記一下這一年碼碼中我須要去了解的基礎知識,有不對的歡迎你們指證出來 https://github.com/TIGERB/car...

  1. 關於設計模式
  2. 關於PHP
  3. 關於互聯網協議

設計模式

面向對象的設計原則
  • 對接口編程,不要對實現編程
  • 使用對象之間的組合,減小對繼承的使用
  • 抽象用於不一樣的事物,而接口用於事物的行爲
設計模式的設計原則
  • 開閉原則:對擴展開放,對修改封閉html

    • mean: 實例的內部不可修改,但能夠增長新功能
  • 依賴倒轉:對接口編程,依賴於抽象而不依賴於具體mysql

    • mean: 就是把公共的拿出來,定義成抽象類、接口、抽象方法,而後你們再去實現這個抽

象,實現的方法各有不一樣,各個實體相互獨立沒有依賴,各個實體離開誰都能活linux

  • 接口隔離:使用多個接口,而不是對一個接口編程,去依賴下降耦合nginx

    • mean: 就是抽象再抽象
  • 最少知道:減小內部依賴,儘量的獨立laravel

    • mean: 實現依賴注入容器,把依賴的實體注入到一個實例(所謂容器)
  • 合成複用:多個獨立的實體合成聚合,而不是使用繼承git

    • mean:儘量不用繼承,使用以上三種方式構成代碼結構
  • 里氏代換:超類(父類)出現的地方,派生類(子類)均可以出現github

    • mean:能用父類實現的子類也能實現
簡單設計原則
  • 經過全部測試:及需求爲上
  • 儘量的消除重複:高內聚低耦合
  • 儘量的清晰表達:可讀性
  • 更少代碼元素:常量,變量,函數,類,包 …… 都屬於代碼元素,下降複雜性
  • 以上四個原則的重要程度依次下降
核心:高內聚鬆耦合(單一職責),外部依賴,實體對抽象編程,抽象就是分層

PHP

client和nginx簡易交互過程
  • step1:client發起http請求
  • step2:dns服務器解析域名獲得主機ip
  • step3:默認端口爲80,經過ip+port創建tcp/ip連接
  • step4:創建鏈接的tcp/ip三次握手,創建成功發送數據包
  • step5:nginx匹配請求web

    • case .html: 靜態內容,分發靜態內容響應
    • case .php: php腳本,轉發請求內容到php-fpm進程,分發php-fpm返回的內容響應
  • step6:斷開鏈接的tcp/ip四次握手,斷開鏈接
nginx和php簡易交互過程
  • 背景:web server和服務端語言交互依賴的是cgi(Common Gateway Interface)協議,因爲cgi效率不高,後期產生了fastcgi協議(一種常駐型的cgi協議),php-cgi實現了fastcgi,可是相比php-cgi,php-fpm提供了更好的PHP進程管理方式,能夠有效控制內存和進程、能夠平滑重載PHP配置
  • 流程:redis

    • step1:nginx接收到一條http請求,會把環境變量,請求參數轉變成php能懂的php變量
    // nginx 配置資料
    location ~ \.php$ {
          include snippets/fastcgi-php.conf; //step1
          fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }
    • step2:nginx匹配到.php結尾的訪問經過fastcgi_pass命令傳遞給php-fpm.sock文件,其實這裏

的ngnix發揮的是反向代理的角色,把http協議請求轉到fastcgi協議請求

// nginx 配置資料
location ~ \.php$ {
      include snippets/fastcgi-php.conf;
      fastcgi_pass unix:/run/php/php7.0-fpm.sock;// step2
}
  • step3:php-fpm.sock文件會被php-fpm的master進程所引用,這裏nginx和php-fpm使用的是

linux的進程間通訊方式unix domain socks,是一種基於文件而不是網絡底冊協議的通訊方式

  • step4:php-fpm的master進程接收到請求後,會把請求分發到php-fpm的子進程,每一個php-fpm

子進程都包含一個php解析器

  • step5:php-fpm進程處理完請求後返回給nginx
知識碎片
//phpfpm配置

pm.max_children = 最大併發數

詳細的答案:
pm.max_children 表示 php-fpm 能啓動的子進程的最大數量。
由於 php-fpm 是多進程單線程同步模式,即一個子進程同時最多處理一個請求,因此子進程數等於最大併發數。
//日誌調試方法

/**
 * 超級調試
 *
 * 調試非本地環境或分佈式環境,經過Log查看變量傳遞
 * 寫入變量值到\var\log\php_super_debug.log
 * @param  mixed  $data     日誌數據
 * @param  string $log_path 日誌路徑
 * @param  string $log_name 日誌名稱
 * @return void       
 */
function super_debug($data, $log_path='\var\log\', $log_name='debug')
{
  error_log(json_encode($data, JSON_UNESCAPED_UNICODE)."\n", 3, $log_path.$log_name);
}
// php實現下載圖片

header('Content-type: image/jpeg');
header('Content-Disposition: attachment; filename=download_name.jpg');
readfile($yourFilePath);
// php5.6開始幹掉了@語法,php上傳圖片兼容版本寫法

if (class_exists('\CURLFile')) {
    curl_setopt($curl, CURLOPT_SAFE_UPLOAD, true);
    $data = array('file' => new \CURLFile(realpath($destination)));//5.5+
} else {
    if (defined('CURLOPT_SAFE_UPLOAD')) {
        curl_setopt($curl, CURLOPT_SAFE_UPLOAD, false);
    }
    $data = array('file' => '@' . realpath($destination));//<=5.5
}
// 序列化與反序列化

概念:
序列化:把變量(全部類型)轉成能傳輸和儲存的變量(不丟失原變量的屬性和結構)
反序列化:把字符串轉成原變量

函數:
序列化:serialize, json_encode(不能序列化對象)
反序列化:unserialize, json_decode
// 記一個坑

ip2long函數
- 32位系統下會轉成帶符號的int,範圍-2^31~2^31-1
- 64位系統下會轉成帶不符號的int,範圍0~2^32-1
# redis發佈訂閱
ini_set(‘default_socket_timeout’, -1);

$redis = new \Redis();
$redis->pconnect('127.0.0.1', 6379);

//訂閱
$redis->subscribe(['msg'], 'callfun');

function callfun($redis, $channel, $msg)
{
  var_dump([
    'redis' => $redis,
    'channel' => $channel,
    'msg' => $msg
  ]);
}

//發佈
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$redis->publish('msg', 'moon cake');
$redis->close();
技巧
  • linux

    • df -h: 更易讀的查看磁盤空間
    • du -h --max-depth=1 file_path:查看文件夾佔用的空間,--max-depth文件夾下顯示層級
    • sudo rm -rf *.log:清理日誌
    • socket

      • http socket = ip:port
      • unix domain socket: unix process communication 進程間通訊
    • ubuntu16.04安裝php5源:sudo apt-add-repository ppa:ondrej/php
    • ubuntu中文支持:sudo apt-get install language-pack-zh-hant language-pack-zh-hans
  • mysql

    • 數據清理:TRUNCATE TABLE XXX
    • 水平分表:MERGE關鍵字
    • 徹底克隆一張表:

      • 克隆表結構:CREATE TABLE table_copy LIKE table_destination
      • 克隆數據:INSERT INTO table_copy SELECT * FORM table_destination
    • 重命名字段:ALTER TABLE table_destination CHANGE column_destination new_name data_type
    • 導出數據: mysqldump -h 127.0.0.1 -u root -p "database_name" "table_name" --where="condition" > file_name.sql
    • 導入數據:source "flie"
  • php:

    • json_encode($data, JSON_UNESCAPED_UNICODE)
    • php的自定義頭信息均可以使用$_SERVER['HTTP_*']來獲取
    • 若是你想知道腳本開始執行(譯註:即服務器端收到客戶端請求)的時刻,使用$_SERVER[‘REQUEST_TIME’]要好於time()
    • error_log(json_encode($data, JSON_UNESCAPED_UNICODE), 1/3, 'tigerbcoder@gmail.com/log_path')
    • sudo watch service php5.6-fpm status
    • foreach後的好習慣reset指針位置,unset掉$key,$value
    • curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    • laravel ['lærə,vɛl]
    • php中的語言結構:echo,exit(),print,empty(),unset(),isset(),list(),eval(),array()
  • git:

    • git commit --amend 重寫最近commit message
    • git cherry-pick 移花接木
  • composer:

    • 修改包來源: sudo composer config repositories.包名 vcs 包地址
PHP的不足
  • PHP仍是有不少不足的地方,好比沒法進行高效的運算

互聯網協議

  • 歸納:從上到下,越上越接近用戶,越下越接近硬件
  • 應用層:

    • 規定應用程序的數據格式
    • [HEAD(以太網標頭) [HEAD(IP標頭) [HEAD(TCP標頭) DATA(應用層數據包)]]]
  • 傳輸層(端口到端口的通訊):

    • 端口:

      • 0到65535(2^16)的整數
      • 進程使用網卡的編號
      • 經過IP+mac肯定主機,只要肯定主機+端口(套接字socket),就能進行程序間的通訊
    • UDP協議:

      • 數據包中加入端口依賴的新協議
      • 數據包[HEAD(發送、接收mac) [HEAD(發送、接收ip) [HEAD(發送、接收端口) DATA]]]
      • 簡單,可靠性差,不知道對方是否接受包
    • TCP協議:

      • 帶有確認機制的UDP協議
      • 過程複雜,實現困難,消耗資源
      tcp/ip connect: tcp/ip的三次握手
                syn握手信號
                ------------->
                syn/ack確認字符
        client  <-------------  server
                ack確認包
                -------------->
  • 網絡層(主機到主機的通訊):

    • IP協議

      • ipv4:

        • 32個二進制位表示,由網絡部分和主機部分構成,
        • 子網掩碼: 網絡部分都爲1,主機部分都爲0,目的判斷ip的網絡部分,如255.255.255.0(11111111.11111111.11111111.00000000)
        • IP數據包:標頭Head+數據Data,放進以太網數據包的Data部分[HEAD [HEAD DATA]]
        • IP數據包的傳遞:

          • 非同一網絡:沒法得到mac地址,發送數據到網關,網關處理
          • 同一網絡:mac地址填寫FF:FF:FF:FF:FF:FF:FF,廣播數據,對比ip,不符合丟包
  • 連接層:

    • 定義數據包(幀Frame)

      • 標頭(Head):數據包的一些說明項, 如發送者、接收者、數據類型
      • 數據(Data):數據包的具體內容
      • 數據包:[HEAD DATA]
    • 定義網卡和網卡惟一的mac地址

      • 以太網規定接入網絡的全部終端都應該具備網卡接口,數據包必須是從一個網卡的mac地址到另外一網卡接口的mac地址
      • mac全球惟一,16位16位進制組成,前6廠商編號,後6網卡流水號
    • 廣播發送數據

      • 向本網絡內的全部設備發送數據包,對比接收者mac地址,不是丟包,是接受
  • 實體層:

    • 終端(pc,phone,pad...)的物理鏈接(光纜,電纜,路由...),負責傳遞0和1信號

掃面下方二維碼關注個人技術公衆號,及時爲你們推送個人原創技術分享

圖片描述

相關文章
相關標籤/搜索