本篇文章更新時間:2022/05/18
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣 或 新台幣 贊助支持。
這篇來整理一下最近開發專案時,發現有不少可以復用的方法。
不全然都是使用 WordPress 內建提供的方法,有時候會是在非 WordPress 安裝的環境驗證演算法與操作,效率更高。
之後有常用的方法就來更新這篇~
需要網路爬取資料(API請求)
function mxp_do_request(string $url, string $type = 'GET', array $headers = [], array $post_fields = [], string $user_agent = '', string $referrer = '', bool $follow = true, bool $use_ssl = false, int $con_timeout = 10, int $timeout = 40) {
$crl = curl_init($url);
curl_setopt($crl, CURLOPT_CUSTOMREQUEST, $type);
curl_setopt($crl, CURLOPT_USERAGENT, $user_agent);
curl_setopt($crl, CURLOPT_REFERER, $referrer);
if ($type == 'POST') {
curl_setopt($crl, CURLOPT_POST, true);
if (!empty($post_fields)) {
curl_setopt($crl, CURLOPT_POSTFIELDS, $post_fields);
}
}
if (!empty($headers)) {
curl_setopt($crl, CURLOPT_HTTPHEADER, $headers);
}
curl_setopt($crl, CURLOPT_FOLLOWLOCATION, $follow);
curl_setopt($crl, CURLOPT_CONNECTTIMEOUT, $con_timeout);
curl_setopt($crl, CURLOPT_TIMEOUT, $timeout);
curl_setopt($crl, CURLOPT_SSL_VERIFYHOST, $use_ssl);
curl_setopt($crl, CURLOPT_SSL_VERIFYPEER, $use_ssl);
curl_setopt($crl, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($crl, CURLOPT_RETURNTRANSFER, true);
$call_response = curl_exec($crl);
curl_close($crl);
return $call_response; //Return data
}
上面是 PHP cURL 實作的版本,下方則是套用 WordPress 內建方法的改版,同樣參數,替換實作內容就可以無縫切入。
function mxp_do_request(string $url, string $type = 'GET', array $headers = [], array $post_fields = [], string $user_agent = '', string $referrer = '', bool $follow = true, bool $use_ssl = false, int $con_timeout = 10, int $timeout = 40) {
$args = array(
'method' => $type,
'timeout' => $timeout,
'redirection' => 5,
'httpversion' => '1.1',
'blocking' => true,
'sslverify' => $use_ssl,
'headers' => [
'User-Agent' => $user_agent,
'Referer' => $referrer,
],
'body' => $post_fields,
);
if (!empty($headers) && count($headers) != 0) {
foreach ($headers as $key => $header) {
$args['headers'][$key] = $header;
}
}
$response = wp_remote_request($url, $args);
$body = wp_remote_retrieve_body($response);
return $body;
}
下載檔案
cURL 簡易的下載檔案方式,適用下載檔案資源路徑(URL)包含檔案名稱與檔案類型(MIME Type)明確不帶其他 Query String 的作法
function mxp_download_source($url, $name) {
$name_path = $name;
$suffix = end(explode('.', $url));
$file_name = dirname(__FILE__) . "/" . $name_path . "." . $suffix;
if (file_exists($file_name)) {
return $file_name;
}
$fp = fopen($file_name, 'w+');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FILE, $fp);
$data = curl_exec($ch);
curl_close($ch);
fclose($fp);
fputs($fp, $data);
fclose($fp);
return $file_name;
}
下載 .gz
壓縮格式的檔案,並解壓縮
function mxp_download_source($url) {
$path = basename(parse_url($url, PHP_URL_PATH));
$file_name = dirname(__FILE__) . "/" . $path;
$buffer_size = 4096; // read 4kb at a time
$out_file_name = str_replace('.gz', '', $file_name);
if (file_exists($out_file_name)) {
return $out_file_name;
}
$fp = fopen($file_name, 'w');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FILE, $fp);
$data = curl_exec($ch);
curl_close($ch);
fclose($fp);
$file = gzopen($file_name, 'rb');
$out_file = fopen($out_file_name, 'wb');
while (!gzeof($file)) {
fwrite($out_file, gzread($file, $buffer_size));
}
fclose($out_file);
gzclose($file);
unlink($file_name);
return $out_file_name;
}
算文字檔案總行數(適用大檔案)
//https://stackoverflow.com/questions/2162497/efficiently-counting-the-number-of-lines-of-a-text-file-200mb
$file = new SplFileObject($source_file);
$file->seek(PHP_INT_MAX);
$total_lines = $file->key() + 1;
照行數讀取文字檔案內容
$file = new SplFileObject($filename);
$line = '';
$file_number = get_total_lines($filename);
$left_items = $file_number % 5000;
for ($i = 1; $i <= $file_number; ++$i) {
if (!$file->eof()) {
//https://stackoverflow.com/questions/5775452/php-read-specific-line-from-file
$file->seek($i);//帶入行號
$line = $file->current();//取得該行內容
}
}
下載遠端圖片並上傳 WordPress 媒體庫與加入文章精選圖片
function mxp_download_and_insert_wp($link = '', $author_id = 1, $post_parent = 0, $att_title = '', $att_content = '', $set_post_thumbnail = true) {
if ($link == '') {
return false;
}
require_once ABSPATH . 'wp-admin/includes/media.php';
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/image.php';
$filename = basename(parse_url($link, PHP_URL_PATH));
$options = array('timeout' => 300);
$upload_file = null;
$response = wp_safe_remote_get($link, $options);
if (!is_wp_error($response)) {
$data = wp_remote_retrieve_body($response);
$upload_file = wp_upload_bits($filename, null, $data);
} else {
return false;
}
$wp_filetype = wp_check_filetype($filename, null);
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_parent' => $post_parent,
'post_author' => $author_id,
'post_title' => preg_replace('/\.[^.]+$/', '', $att_title),
'post_content' => $att_content,
'post_status' => 'inherit',
);
$attachment_id = wp_insert_attachment($attachment, $upload_file['file'], $post_parent);
if (!is_wp_error($attachment_id)) {
//產生附加檔案中繼資料
$attachment_data = wp_generate_attachment_metadata($attachment_id, $upload_file['file']);
wp_update_attachment_metadata($attachment_id, $attachment_data);
//將圖像的附加檔案設為特色圖片
$type = explode("/", $wp_filetype['type']);
if ($set_post_thumbnail && $type[0] == 'image') {
set_post_thumbnail($post_parent, $attachment_id);
}
return true;
} else {
return false;
}
}
這個方法我這樣寫應該算是很 WordPress 的原生處理方式了,網路上還有其他網友分享的方法也可以參考: Gist: Upload an image to WordPress media gallery from URL
WooCommerce 訂單相關方法
以前有專門寫過一篇取訂單各項欄位資料的方法,包含顧客、訂單、結帳資料等。
參考: [WooCommerce] 程式開發時取出訂單資訊的方法整理
如果開發上或是「效能優先」的話,我會包過一個方法,一次從 postmeta
資料表裡取出訂單附加資訊,免的一個方法去呼叫一次資料庫的讀取,一次取得全部來操作,效率比較好。
function mxp_get_order_post_meta($order_id) {
global $wpdb;
$order_meta = $wpdb->get_results("SELECT meta_key,meta_value FROM wp_postmeta WHERE post_id = " . $order_id, ARRAY_A);
if (count($order_meta) == 0) {
return false;
}
$arr = array();
foreach ($order_meta as $key => $meta) {
$arr[$meta['meta_key']] = $meta['meta_value'];
}
return $arr;
}