function send_sms($mobile, $msg) {
$authKey = 'YOUR_AUTH_KEY';
$senderId = 'YOUR_SENDER_ID'; // 6 字元
$post = [
'authkey' => $authKey,
'mobiles' => $mobile,
'message' => urlencode($msg),
'sender' => $senderId,
'route' => 'template',
];
$ch = curl_init('https://control.msg91.com/sendhttp.php');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
]);
return curl_exec($ch);
}
function send_email($to, $subject, $html) {
require 'Mandrill.php';
$m = new Mandrill('YOUR_API_KEY');
$message = [
'html' => $html, 'text' => strip_tags($html),
'subject' => $subject, 'from_email' => 'noreply@example.com',
'from_name' => 'MyApp', 'to' => [['email' => $to]],
'track_opens' => true,
];
return $m->messages->send($message);
}
function mail_html($to, $subject, $body) {
$headers = "From: MyApp \r\n";
$headers .= "Reply-To: noreply@example.com\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=UTF-8\r\n";
return mail($to, $subject, $body, $headers);
}
function clean($input) {
if (is_array($input)) return array_map('clean', $input);
$out = (string)$input;
if (get_magic_quotes_gpc()) $out = stripslashes($out);
return htmlentities($out, ENT_QUOTES, 'UTF-8');
}
function is_valid_email($email) {
return (bool)filter_var($email, FILTER_VALIDATE_EMAIL);
}
function is_valid_url($url) {
return (bool)filter_var($url, FILTER_VALIDATE_URL);
}
function get_real_ip() {
foreach (['HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR'] as $key) {
if (!empty($_SERVER[$key])) return $_SERVER[$key];
}
return 'unknown';
}
$deny = file_exists('blocked_ips.txt') ? file('blocked_ips.txt', FILE_IGNORE_NEW_LINES) : ['127.0.0.1'];
if (in_array(get_real_ip(), $deny)) { die('Your IP is blocked'); }
function force_download($file, $dir = '../log/exports/') {
$path = $dir . $file;
if (!is_file($path)) die('File not found');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $file . '"');
header('Content-Length: ' . filesize($path));
readfile($path);
exit;
}
function create_zip(array $files, $dest, $overwrite = false) {
if (file_exists($dest) && !$overwrite) return false;
$zip = new ZipArchive();
if ($zip->open($dest, $overwrite ? ZipArchive::OVERWRITE : ZipArchive::CREATE)) {
foreach ($files as $f) if (file_exists($f)) $zip->addFile($f, basename($f));
$zip->close();
return file_exists($dest);
}
return false;
}
function unzip($zipFile, $destDir) {
$zip = new ZipArchive();
if ($zip->open($zipFile) && $zip->extractTo($destDir)) {
$zip->close(); return true;
}
return false;
}
function read_csv($file) {
$data = [];
if (($h = fopen($file, 'r')) !== false) {
while (($row = fgetcsv($h, 1024)) !== false) $data[] = $row;
fclose($h);
}
return $data;
}
function write_csv(array $data, $file) {
$h = fopen($file, 'w');
foreach ($data as $row) fputcsv($h, $row);
fclose($h);
}
function list_dir($dir) {
$out = [];
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS)) as $f) {
$out[] = $f->getPathname();
}
return $out;
}
function delete_dir($path) {
if (is_dir($path)) {
foreach (array_diff(scandir($path), ['.','..']) as $f) delete_dir($path . '/' . $f);
return rmdir($path);
}
return is_file($path) && unlink($path);
}
function resize_img($src, $dst, $maxW, $maxH) {
list($w, $h, $type) = getimagesize($src);
if ($w <= $maxW && $h <= $maxH) return copy($src, $dst);
$ratio = min($maxW/$w, $maxH/$h);
$nw = (int)($w * $ratio); $nh = (int)($h * $ratio);
$srcImg = match($type) {
IMAGETYPE_JPEG => imagecreatefromjpeg($src),
IMAGETYPE_PNG => imagecreatefrompng($src),
IMAGETYPE_GIF => imagecreatefromgif($src),
default => null,
};
$dstImg = imagecreatetruecolor($nw, $nh);
imagecopyresampled($dstImg, $srcImg, 0,0,0,0, $nw,$nh, $w,$h);
imagejpeg($dstImg, $dst, 90);
imagedestroy($srcImg); imagedestroy($dstImg);
}
function download_img($url, $saveAs) {
$ch = curl_init($url);
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>1, CURLOPT_BINARYTRANSFER=>1, CURLOPT_FOLLOWLOCATION=>1]);
$data = curl_exec($ch);
curl_close($ch);
return file_put_contents($saveAs, $data) !== false;
}
function remote_filesize($url) {
$ch = curl_init($url);
curl_setopt_array($ch, [CURLOPT_NOBODY=>1, CURLOPT_HEADER=>1, CURLOPT_RETURNTRANSFER=>1, CURLOPT_FOLLOWLOCATION=>1]);
curl_exec($ch);
$size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
curl_close($ch);
return $size > 0 ? $size : 'unknown';
}
function pdf_to_jpg($pdf, $jpg) {
exec("convert -density 150 -quality 90 '$pdf[0]' '$jpg'", $out, $ret);
return $ret === 0;
}
function auto_link($text) {
$text = preg_replace('~((f|ht)tp://\S+)~', '$1', $text);
$text = preg_replace('~(\s)(www\.\S+)~', '$1$2', $text);
$text = preg_replace('~([\w.-]+@[\w.-]+\.\w+)~', '$1', $text);
return $text;
}
function highlight($text, $keywords, $color = '#4285F4') {
foreach (explode(' ', $keywords) as $kw) {
$text = preg_replace("|($kw)|ui", "$1", $text);
}
return $text;
}
function ordinal($n) {
$s = ['th','st','nd','rd'];
$v = $n % 100;
return $n . ($s[($v < 20 || $v > 20) ? ($v % 10 < 4 ? $v % 10 : 0) : 0]);
}
function secs_to_str($secs) {
$units = [86400=>'day', 3600=>'hour', 60=>'minute', 1=>'second'];
$str = '';
foreach ($units as $sec => $unit) {
if ($secs >= $sec) {
$n = (int)($secs / $sec);
$secs %= $sec;
$str .= ($str ? ', ' : '') . "$n $unit" . ($n > 1 ? 's' : '');
}
}
return $str ?: '0 seconds';
}
function detect_city($ip) {
$url = "https://ipinfodb.com/ip_locator.php?ip=" . urlencode($ip);
$html = file_get_contents($url);
preg_match('/City : ([^<]+)/i', $html, $c);
preg_match('/State\/Province : ([^<]+)/i', $html, $s);
return ($c[1] ?? '') . ($s[1] ? ', ' . $s[1] : '');
}
function fb_fans($page) {
$json = @file_get_contents("https://graph.facebook.com/$page");
return $json ? json_decode($json, true)['fan_count'] ?? 0 : 0;
}
function latest_tweet($user) {
$url = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=$user&count=1";
// 需 OAuth 簽名,此處略
}
function tiny_url($url) {
return file_get_contents("https://tinyurl.com/api-create.php?url=" . urlencode($url));
}
function qr_code($data, $size = 150) {
return file_get_contents("https://chart.googleapis.com/chart?chs={$size}x{$size}&cht=qr&chl=" . urlencode($data));
}
function distance_km($lat1, $lon1, $lat2, $lon2) {
$theta = $lon1 - $lon2;
$dist = sin(deg2rad($lat1))*sin(deg2rad($lat2)) + cos(deg2rad($lat1))*cos(deg2rad($lat2))*cos(deg2rad($theta));
return acos($dist) * 6371; // 地球半徑 6371km
}
function whois($domain) {
$servers = ['com'=>'whois.verisign-grs.com', 'net'=>'whois.verisign-grs.com', 'org'=>'whois.pir.org', 'tw'=>'whois.twnic.net.tw'];
$tld = array_pop(explode('.', $domain));
$server = $servers[$tld] ?? 'whois.iana.org';
$fp = fsockopen($server, 43);
fputs($fp, $domain . "\r\n");
$res = '';
while (!feof($fp)) $res .= fgets($fp, 128);
fclose($fp);
return $res;
}
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'user', 'pass', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]);
$json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); $data = json_decode($json, true);
$xml = simplexml_load_string($str); foreach ($xml->item as $it) echo $it->title . "\n";
function current_url() {
$https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443;
return ($https ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
function throttle_download($file, $rateKB = 100) {
$fp = fopen($file, 'rb');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . filesize($file));
while (!feof($fp)) {
echo fread($fp, $rateKB * 1024);
flush();
sleep(1);
}
fclose($fp);
}
function text_to_png($text, $font = 5) {
header('Content-Type: image/png');
$im = imagecreate(200, 50);
$bg = imagecolorallocate($im, 255, 255, 255);
$color = imagecolorallocate($im, 0, 0, 0);
imagestring($im, $font, 10, 15, $text, $color);
imagepng($im);
imagedestroy($im);
}
function exec_time() {
return microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
}
$unique = array_unique($arr); // 索引陣列 $unique = array_unique($arr, SORT_REGULAR); // 關聯陣列保留鍵
function random_str($len = 32) {
return bin2hex(random_bytes($len / 2));
}
$hash = password_hash($pwd, PASSWORD_DEFAULT); // 自動鹽、BCRYPT/ARGON2
if (password_verify($input, $hash)) { /* 登入成功 */ }
function curl_multi_fetch(array $urls, $options = []) {
$mh = curl_multi_init();
$chs = [];
foreach ($urls as $i => $u) {
$ch = curl_init($u);
curl_setopt_array($ch, $options + [CURLOPT_RETURNTRANSFER => true]);
curl_multi_add_handle($mh, $ch);
$chs[$i] = $ch;
}
$running = null;
do { curl_multi_exec($mh, $running); curl_multi_select($mh); } while ($running);
$res = [];
foreach ($chs as $i => $ch) {
$res[$i] = ['content' => curl_multi_getcontent($ch), 'info' => curl_getinfo($ch)];
curl_multi_remove_handle($mh, $ch); curl_close($ch);
}
curl_multi_close($mh);
return $res;
}
mkdir('/path/to/dir', 0755, true);
$fp = fopen('lockfile', 'w+');
if (flock($fp, LOCK_EX)) { /* 關鍵區 */ flock($fp, LOCK_UN); }
fclose($fp);
echo 'Memory: ' . round(memory_get_usage(true) / 1024 / 1024, 2) . ' MB';
spl_autoload_register(function($class) {
$file = __DIR__ . '/src/' . str_replace('\\', '/', $class) . '.php';
if (file_exists($file)) require $file;
});
function dd($var) {
echo ''; var_dump($var); echo '
'; die;
}
這 46 個片段涵蓋 PHP 開發 80% 的高頻需求。建議:將常用函數整理為專案共用的 helpers.php,配合 Composer 自動載入;涉及第三方 API 的片段請務必填入正式金鑰並加入錯誤重試、日誌記錄;生產環境嚴禁使用 dd()、exec() 等除錯/高危函數。持續精簡、封裝、測試,打造屬於團隊的「PHP 瑞士刀」。