肥軟工程師的腦補NTRP2.0 – 2.5攻略

View this post on Instagram

久違的網球

A post shared by James Tien (@southp0105) on

View this post on Instagram

太氣了,邊摳邊打

A post shared by James Tien (@southp0105) on

從學生時代起,網球就一直是我最喜歡的球類運動。小孩出生時中斷了4年多,現在小子長大上場打球了,我也藉機回到場上;重溫樂趣之餘,也想看看自己在比賽中能打到什麼程度。台灣的業餘賽事本來就少,舉辦在北部的少,能以個人名義出賽的少少,能給我這種菜鳥玩的更是少少少。因此在等待下次機會的同時,順便寫篇文章總結一下心得。因為還沒有機會驗證成效,這只能算是『腦補攻略』而已。

謎之音:沒搞錯吧?入門級的比賽還需要攻略喔?

快別這麼說 Q_O 如果能每天練個幾小時,當然是不需要啦。但像俺這種每天摳頂摳不停又要照顧小孩的軟體攻城獅,當然要做點計畫利用有限的資源,提升一點機會。

繼續閱讀 “肥軟工程師的腦補NTRP2.0 – 2.5攻略"

用nginx + docker配置多個WordPress站的基本設定

前幾天和幾位朋友聊到WordPress測試環境的配置。有時候為了測試更貼近實際使用狀況,單靠ChassisVVV的開發環境還遠遠不夠,還需要實際將功能上到有公開網域的WordPress站上才行。這時我比較常用的方法是直接靠nginx做reverse proxy將某個子網域對應到一個WordPress Docker容器,這樣既不用擔心測試中污染環境,從配置到銷毀都快速又乾淨。例如https://jptest.southp.dev/就是我拿來測試Jetpack用的(空空的,沒啥好看的啦)。

因為我只是自己測試用的,所以一直以來我都只用一些很基本的手法來做這件事,沒想聊一聊發現好幾個人都跟我一樣,不需要用到這麼多複雜的套件,只想要非常簡單的方法就好,所以寫這篇文章簡述一下。

繼續閱讀 “用nginx + docker配置多個WordPress站的基本設定"

我們與PHP的距離(二): 任性的大小寫

本系列專為從PHP之外的語言開啟碼農人生、卻因命運安排整天與PHP為伍的人撰寫,收集一些從其他語言的角度看來不可思議的設計。如果能讓在讀這篇文章的你在實務上踩到而懷疑人生前就釋懷,就是我莫大的榮幸。

前言

前篇gethostbyname(),本篇討論少見於PHP之外的設計:varying case sensitivity,也就是某些情況下大小寫相關,某些情況下大小寫無關。總之,就是任性。

可能因為我個人有經年累月的大小寫相關的程式編寫習慣,再加上linter層層把關,我大概兩年多才發現有這個特性,當下簡直是晴天霹靂、茅廁頓開,在這非黑即白的大小寫相關性世界,PHP竟仍能為我們開一扇窗;彷彿在提醒我們,看待世間萬物切勿抱持成見,才能看見真實。

常有人說PHP是如詩般的語言,這,何嘗不正是其獨有的詩意呢?

嘴夠了,進入正題

更精確來講,PHP的大小寫相關性是:

  • 函式名、命名空間名與類別名大小寫無關
  • 變數名、常數名大小寫相關

啊啊啊啊啊啊啊啊啊啊啊啊啊

大部分的時候這都只會造成一些小驚喜,像這樣:

class Foo {
    const ABC = 'I am a constant';
    static function bar() { ... }
}
$poetry = 'I am a variable';

Foo::bar();  // 可以
foo::Bar();  // 嗯,有何不可
print_r( $poEtry ); // 不行喔
print_r( Foo::aBC ); // 討厭,就說不行了,都欺負人家 ...

但一個沒站穩,玻璃心還是會摔碎的。

繼續閱讀 “我們與PHP的距離(二): 任性的大小寫"

我們與PHP的距離(一): gethostbyname()

前言

自從加入a8c,PHP作為常備語言之一,時至今日仍然像顆出奇蛋一樣止不盡的驚喜。天底下沒有完美的語言,但至今確實沒有任何一個我寫過的程式語言比PHP讓我感到更『魔幻』。本系列專為從PHP之外的語言開啟碼農人生、卻因命運安排整天與PHP為伍的人撰寫,收集一些從其他語言的角度看來不可思議的設計。如果能讓在讀這篇文章的你在實務上踩到而懷疑人生前就釋懷,莫大的榮幸。

祝各位天天PHP,天天開心。

進入正題

首先來看看今天的主角:gethostbyname() 在文件中是怎麼描述的吧:

gethostbyname ( string $hostname ) : string

Returns the IPv4 address of the Internet host specified by hostname.

舉例來說:

php> print_r( gethostbyname( 'softman.blog' ) );
192.0.78.25
php> print_r( gethostbyname( 'localhost' ) );
127.0.0.1

很簡單吧。這基本上就是一個gethostbyname()系統函式的包裝,

但問題出在它的回傳值設計。根據官方文件:

Returns the IPv4 address or a string containing the unmodified hostname on failure.

『當錯誤發生時,會回傳無修改的hostname引數』

……………..

這神設計有兩個問題。第一,和許多PHP函式的錯誤行為相悖;第二,複雜的錯誤處理讓這個函式很難正確使用。如果你認為:

$hostname === gethostbyname( $hostname )

這樣就結了,那就太小看PHP惹 …

繼續閱讀 “我們與PHP的距離(一): gethostbyname()"

WCEU … 我不來啦 _(´ཀ`」 ∠)_

嗚哇啊啊啊啊啊啊啊啊啊啊啊啊啊啊!

真是世事難料,本來不久前才很興奮這次可以當會眾,沒想到就去不成了 … (´ཀ`」 ∠)

事情是這樣,本來俺是隸屬於全球化小組,大夥為了順道去WCEU大拜拜,就排定6月中在奧地利meetup,結束後就可以一起搭個夜車到柏林參加WCEU,一切計畫看來相當圓滿。殊不知,從今年開始俺們在提升入門使用經驗(onboarding)以及用戶保持率(retention)上的挑戰愈發嚴峻,我先是暫時到onboarding team幫忙四個月,現在則是正是轉調到retention team去了。因此本來的meetup計畫不再適用,為了應付接下來堆積如山的專案,也只好先取消了參加WCEU的計畫。

不!!!!!!我的爽爽玩WordCamp計畫!!!!!

我想要扭腰擺臀地飄到擺攤同事身旁說聲『加油』這經典風涼話啊啊!
我想要在講者們焦頭爛額地在上台前最後修正時遞上一杯咖啡,帶著竊笑飄走啊啊!
我想要去大肆吃免費buffet而不是去忙著補貨啊啊!

看來只好把爽爽玩計畫寄望於今年的WordCamp Taipei了 … 快來人幫我擺攤啊啊啊!

l()有什麼不對

話說PHP因為不像JavaScript內建的log函式庫就挺不錯,不同的源碼中總是可以看到自己的log函式。最常見的不外乎是可以印出任意個引數值到error log / stdout / stderr,或是印出第一個引數後回傳之。

誒~但可能是大家都想盡量少打些字吧,我發現這類函式經常被命名為 l()。對,就一個一柱定海的l

是很精簡啦,而且l這字看久也蠻美的 … 但個人認為這並不是一個好名字。為什麼?因為不夠明顯啊。這就有點像C++為什麼要引入static_cast reinterpret_cast啥的來取代C-style cast,要特別留意的東西應該要盡量設計成引人注目會比較好。

基於這項理由,我自己在用的是mango()guava()litchi()

……………….

……………….

真的啦,有code為證:

function mango( $val ) {
    if ( is_null( $val ) ) {
        return 'NULL';
    } elseif ( false === $val ) {
        return 'FALSE';
    } elseif ( true === $val ) {
        return 'TRUE';
    }

    return print_r( $val, true );
}

function guava() {
    $arg_strs = array_map( 'mango', func_get_args() );
    $log = join( ' ', $arg_strs );

    error_log( $log );
}

function litchi( $arg, $label = 'log value:' ) {
    guava( $label, $arg );
    return $arg;
}

說真的,自從我把這些log函式從WTF系列改成這台灣味的水果系列,整個人debug起來心平氣和,修為都提升了呢 🤪

而且另外的好處是很好搜尋啊。大家在提交源碼前相信公司都會要求把不必要的debugging log都拿掉吧?(啥?你們公司不用?塊陶啊~) 這樣只要ag guava就一定能找出所有的debugging log了呢。雖然也可以用ag '\bl\('找到所有的l()呼叫,但這打起來手就癢癢的,沒這麼順暢呢 … (個人因素

我在某次working tips分享中分享了這個小撇步,會後有人漲紅著臉拿了這個給我看:

function 👻( $val ) {
if ( is_null( $val ) ) {
return 'NULL';
} elseif ( false === $val ) {
return 'FALSE';
} elseif ( true === $val ) {
return 'TRUE';
}
return print_r( $val, true );
}
function 💩() {
$arg_strs = array_map( '👻', func_get_args() );
$log = join( ' ', $arg_strs );
error_log( $log );
}

嗯 … 真是超級明顯又好搜尋呢