PHP經常使用代碼筆記

無彈窗下載

瀏覽器彈窗的安全限制主要在於咱們每每經過 JS 打開新窗口來實現下載
因此繞過安全彈窗問題的核心在於避免 JS 的窗口操做
具體的, 咱們能夠經過建立一個_blank的超連接來返回文件流,實現文件下載php

$filename='xxx.pdf';
$encoded_filename = rawurlencode($filename);
header('Content-type: application/force-download');
header("Content-Transfer-Encoding: binary");
if (preg_match("/MSIE/", $ua) || preg_match("/Trident\/7.0/", $ua) || preg_match("/Edge/", $ua)) {
    header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
} else if (preg_match("/Firefox/", $ua)) {
    header("Content-Disposition: attachment; filename*=\"utf8''" . $file_name . '"');
} else {
    header('Content-Disposition: attachment; filename="' . $file_name . '"');
}
header("Pragma:no-cache");
header("Expires:0");
readfile($filename);

兩點座標距離

兩個逗號分隔的經緯度,bd09座標系、單位米node

function lonlat2distance($lonlat1, $lonlat2) {
    if (empty($lonlat1) || empty($lonlat2))
        return false;

    list($lon1, $lat1) = explode(',', $lonlat1);
    list($lon2, $lat2) = explode(',', $lonlat2);

    $er = 6378137;
    $radlat1 = M_PI * $lat1 / 180.0;
    $radlat2 = M_PI * $lat2 / 180.0;
    $radlong1 = M_PI * $lon1 / 180.0;
    $radlong2 = M_PI * $lon2 / 180.0;

    if ($radlat1 < 0)
        $radlat1 = M_PI / 2 + abs($radlat1);// south
    if ($radlat1 > 0)
        $radlat1 = M_PI / 2 - abs($radlat1);// north
    if ($radlong1 < 0)
        $radlong1 = M_PI * 2 - abs($radlong1);// west
    if ($radlat2 < 0)
        $radlat2 = M_PI / 2 + abs($radlat2);// south
    if ($radlat2 > 0)
        $radlat2 = M_PI / 2 - abs($radlat2);// north
    if ($radlong2 < 0)
        $radlong2 = M_PI * 2 - abs($radlong2);// west

    $x1 = $er * cos($radlong1) * sin($radlat1);
    $y1 = $er * sin($radlong1) * sin($radlat1);
    $z1 = $er * cos($radlat1);
    $x2 = $er * cos($radlong2) * sin($radlat2);
    $y2 = $er * sin($radlong2) * sin($radlat2);
    $z2 = $er * cos($radlat2);
    $d = sqrt(($x1 - $x2) * ($x1 - $x2) + ($y1 - $y2) * ($y1 - $y2) + ($z1 - $z2) * ($z1 - $z2));
    $dist = acos(($er * $er + $er * $er - $d * $d) / (2 * $er * $er)) * $er;
    return intval($dist);
}

獲取客戶端IP

/**
     * 客戶端ip地址
     * @param $type  0互聯網地址xxx.xxx.xxx.xxx,1整型地址12345678
     * @return mixed
     */
    function getClientIp($type = 0){
        $type = $type ? 1 : 0;
        static $ip = NULL;

        if ($ip !== NULL)
            return $ip[$type];

        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            $pos = array_search('unknown', $arr);
            if (false !== $pos) unset($arr[$pos]);
            $ip = trim($arr[0]);
        } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }

        $long = sprintf("%u", ip2long($ip));
        $ip = $long ? [$ip, $long] : ['0.0.0.0', 0];

        return $ip[$type];
    }

註解:
REMOTE_ADDR是可信的實際上的直接與服務器通訊的主機, 但客戶端ip每每會被負載均衡節點或者代理服務器隔離
HTTP_* 系列變量是不可信的, 他們取自Http報文頭部, 可被僞造。 若不考慮僞造, 則正常狀況下能反映出客戶端真實ipmysql

  • HTTP_X_FORWARDED_FOR 能反應出代理層次。 格式爲 「客戶端ip,代理1的ip,代理2的ip,...」
  • HTTP_CLIENT_IP 不考慮僞造狀況下, 它反應了真實客戶端ip. 因爲還沒有歸入標準, 雖然存在於http頭部, 但部分服務器不支持解析

Unicode解碼

function unicodeDecode($str) {
        return preg_replace_callback(
            '/\\\\u([0-9a-f]{4})/i',
            function($match){return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');},
            $str
        );
    }

CURL

#基礎示例
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//curl_setopt($ch, CURLOPT_POST,  true );
//curl_setopt($ch, CURLOPT_POSTFIELDS,  $data); #上傳文件時指定文件字段爲: 文件名前面加上@前綴並使用完整路徑
//curl_setopt($ch, CURLOPT_FILE, $file_handler); //指定curl拉取到數據的文件保存路徑
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
//curl_setopt($ch, CURLOPT_TIMEOUT, 500);
//curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type:application/json'));
//curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookiefile.txt');  #指定請求須要帶上的cookie的文件路徑
//curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookiefile.txt');   #指定響應返回的cookie存入的文件路徑
$res = curl_exec($ch);
curl_close($ch);

#也可用array傳入選項參數
curl_setopt_array($ch, array(
	CURLOPT_URL             =>    'http://www.example.com/',
	CURLOPT_RETURNTRANSFER  =>     true,
));

#基於curl作http請求封裝
class Http
{
    public function post($api, $data = array())
    {
        return $this->http('get', $api, $data);
    }

    public function get($api, $data = array())
    {
        return $this->http('post', $api, $data);
    }

    public function put($api, $data = array())
    {
        return $this->http('put', $api, $data, array('X-HTTP-Method-Override: PUT'));
    }

    protected function http($type, $api, $data, $headers = array())
    {
        switch ($type) {
            case 'post':
                $is_post = true;
                break;
            case 'get':
            case 'put':
            default:
                $is_post = false;
                break;
        }

        $data = (gettype($data) == 'array') ? http_build_query($data) : $data;

        $ch = curl_init();

        if (!$is_post && $data) {
            $api .= "?{$data}";
        }

        curl_setopt($ch, CURLOPT_URL, $api);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        if ($is_post) {
            curl_setopt($ch, CURLOPT_POST, $is_post);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        }

        $res = curl_exec($ch);
        curl_close($ch);

        return $res;
    }
}

PDO導數據

$config = array(
    'host'      =>  '127.0.0.1',
    'port'      =>  '3306',
    'dbname'    =>  'xx',
    'username'  =>  'xx',
    'password'  =>  'xx',

    'transaction' => true,

    'pagesize'  =>  1000,
);

set_time_limit(0);
error_reporting(E_ALL);
ini_set('log_errors', 'on');
ini_set('display_errors', true);
ini_set('memory_limit', '1024M');

echo ("-- 數據處理開始 --");
try{
    $dsn = "mysql:dbname={$config['dbname']};host={$config['host']};port={$config['port']}";
    $dbh = new PDO($dsn, $config['username'], $config['password']);
    $dbh->exec('SET NAMES utf8');

    $config['transaction'] AND $dbh->beginTransaction();
	$dbh->exec('truncate table xxx');
	$sthS = $dbh->prepare("select * from xxx limit ?, {$config['pagesize']}");
	$sthI = $dbh->prepage('insert into yyy(a,b,c) values(?,?,?)');

	$start = 0;
	while ($sthS->execute(array($start)) && $datas = $sthS->fetchAll(PDO::FETCH_OBJ)) {
		foreach ($datas as $data) {
			$sthI->execute(array(
					$data->a,
					$data->b,
					$data->c,
				));
		}

		$start += $config['pagesize'];
	}

	$config['transaction'] AND $dbh->commit();

} catch (Exception $e) {
    $config['transaction'] AND $dbh->rollBack();
    exit("-- 異常 --\n" . $e->getMessage());
}

​exit('-- 數據處理結束 --');

xml處理筆記

$xml = simplexml_load_string($xml_str, 'SimpleXMLElement', LIBXML_NOCDATA);
$xml = simplexml_load_file($xml_str, 'SimpleXMLElement', LIBXML_NOCDATA);

$xml->getName()
    ->children()
    ->$node
    
foreach ($xml as $element) {}

讀取服務器環境信息

# root鏈接數據庫來提權,從而下面mysql_get_server_info能讀取數據庫版本信息
mysql_connect(數據庫ip, root帳號, root密碼);

$info = array(
    '操做系統'		=>	PHP_OS,
    '服務器環境'		=>	$_SERVER["SERVER_SOFTWARE"],
    'PHP環境'		=>	PHP_VERSION.'/'.php_sapi_name(),
    'MySQL版本'		=>	mysql_get_server_info(),
    '主機信息'		=>	$_SERVER['SERVER_NAME'].':'.$_SERVER['SERVER_PORT'].' '.$_SERVER['SERVER_PROTOCOL'],
    'WEB目錄'		=>	$_SERVER["DOCUMENT_ROOT"],
    '服務器域名/IP'	=>	$_SERVER['SERVER_NAME'].' [ '.gethostbyname($_SERVER['SERVER_NAME']).' ]',
    '服務器時間'	        =>	date("Y年n月j日 H:i:s"),
    '北京時間'		=>	gmdate("Y年n月j日 H:i:s",time()+8*3600),
    '執行時間限制'	=>	ini_get('max_execution_time').'秒',
    '上傳附件限制'	=>	ini_get('upload_max_filesize'),
    '剩餘空間'		=>	round((disk_free_space(".")/(1024*1024)),2).'M',
);

經常使用$_SERVER變量

#當前腳本名
PHP_SELF #腳本的web路徑 及 pathinfo信息
SCRIPT_NAME #腳本的web路徑(CGI模式下則始終返回 /cgi-system/php.cgi )
REQUEST_URI #完整的請求路徑
SCRIPT_FILENAME #腳本文件的絕對路徑
其中 `__FILE__ == $_SERVER['DOCUMENT_ROOT'] . $SERVER['SCRIPT_NAME'] ;`

#其餘變量
SERVER_ADDR #服務器IP
SERVER_NAME #服務器主機名
REMOTE_ADDR #客戶機IP
REMOTE_HOST #客戶機主機名
QUERY_STRING #查詢字符串
DOCUMENT_ROOT #WEB根目錄

批量給圖片打水印

set_time_limit(0);
error_reporting(E_ALL);
ini_set('memory_limit', '1024M');
//ini_set('display_errors', true);

$rawdir = 'images';
$savedir = 'watermarked_images';
$watermark_png = 'watermark.png';

//開始打水印
$watermark = imagecreatefrompng($watermark_png);
list($waterW, $waterH) = getimagesize($watermark_png);
$dir = opendir($rawdir);

while (false  !== ( $file  =  readdir ($dir))) {
	if ($file=='.' || $file=='..') continue;
	$path = sprintf('%s/%s/%s', realpath('.'), $rawdir, $file);
	$savepath = sprintf('%s/%s/%s', realpath('.'), $savedir, $file); 

	list($imageW, $imageH) = getimagesize($path);
	$x = ($imageW - $waterW) / 2;
	$x = $x > 0 ? round($x) : 0;
	$y = ($imageH - $waterH) / 2;
	$y = $y > 0 ? round($y) : 0;
	
	$ext = pathinfo($path, PATHINFO_EXTENSION);
	switch ($ext) {
		case 'jpg':
		case 'jpeg':
			$image = imagecreatefromjpeg($path);
			imagecopy($image, $watermark, $x, $y, 0, 0, $waterW, $waterH);
			imagejpeg($image, $savepath);
			break;
		case 'png':
			$image = imagecreatefrompng($path);
			imagecopy($image, $watermark, $x, $y, 0, 0, $waterW, $waterH);
			imagepng($image, $savepath);
			break;
		case 'gif':
			$image = imagecreatefromgif($path);
			imagecopy($image, $watermark, $x, $y, 0, 0, $waterW, $waterH);
			imagegif($image, $savepath);
			break;
		default:
			continue;
			break;
	}

	imagedestroy ($image);
}

closedir($dir);
echo "\n\n\n圖片打水印完畢\n\n\n";
相關文章
相關標籤/搜索