<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>語法筆記 on Tom 除錯中</title><link>https://tomleesm.github.io/tags/%E8%AA%9E%E6%B3%95%E7%AD%86%E8%A8%98/</link><description>Recent content in 語法筆記 on Tom 除錯中</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Mon, 24 Apr 2023 17:50:21 +0800</lastBuildDate><atom:link href="https://tomleesm.github.io/tags/%E8%AA%9E%E6%B3%95%E7%AD%86%E8%A8%98/index.xml" rel="self" type="application/rss+xml"/><item><title>PHP 物件導向語法筆記</title><link>https://tomleesm.github.io/posts/2023/04/php-oop/</link><pubDate>Mon, 24 Apr 2023 17:50:21 +0800</pubDate><guid>https://tomleesm.github.io/posts/2023/04/php-oop/</guid><description>&lt;p&gt;參考 &lt;a href="https://www.php.net/manual/en/language.oop5.php"&gt;PHP 官方文件&lt;/a&gt; ，沒看過、記不起來，或覺得有必要的才在這裡寫筆記。&lt;/p&gt;
&lt;h2 id="properties"&gt;Properties&lt;/h2&gt;
&lt;p&gt;class 中的變數，至少要有一個修飾詞 &lt;a href="https://www.php.net/manual/en/language.oop5.visibility.php"&gt;Visibility&lt;/a&gt;、 &lt;a href="https://www.php.net/manual/en/language.oop5.static.php"&gt;Static Keyword&lt;/a&gt; 或是 &lt;a href="https://www.php.net/manual/en/language.oop5.properties.php#language.oop5.properties.readonly-properties"&gt;readonly&lt;/a&gt; (PHP 8.1.0 以上)。宣告時的初始值必須是常數(基本型別或 constant )，表示必須在編譯時期確定其值，而不是在 runtime 時。沒有 Visibility 的屬性，預設是 public，所以 &lt;code&gt;static $var = 1&lt;/code&gt; ，則此屬性預設是 public&lt;/p&gt;
&lt;p&gt;PHP 7.4.0 開始，可以有 &lt;a href="https://www.php.net/manual/en/language.types.declarations.php#language.types.declarations"&gt;Type declarations&lt;/a&gt; 的屬性，必須在存取前初始化，否則會丟出 &lt;a href="https://www.php.net/manual/en/class.error.php"&gt;Error&lt;/a&gt; ，不會自動給預設值 0, 0.0F, 或空字串。沒有 &lt;a href="https://www.php.net/manual/en/language.types.declarations.php#language.types.declarations"&gt;Type declarations&lt;/a&gt; 的屬性 ( 例如 &lt;code&gt;public $var&lt;/code&gt;)，則會給預設值 &lt;code&gt;null&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="class-constants"&gt;Class Constants&lt;/h2&gt;
&lt;p&gt;一個類別建立一個 class constant，不是一個物件建立一個。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="nx"&gt;php&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;C&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getConstant&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;C&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;class constant C 只有一個，歸屬於類別 A，即使是 &lt;code&gt;new&lt;/code&gt; 三個物件 A，分給變數 &lt;code&gt;$a1&lt;/code&gt;, &lt;code&gt;$a2&lt;/code&gt; 和 &lt;code&gt;$a3&lt;/code&gt;，也只有一個 class constant C，所以使用 &lt;code&gt;$a1::C&lt;/code&gt; 存取，不是 &lt;code&gt;$a1-&amp;gt;C&lt;/code&gt;，在內部存取是用 &lt;code&gt;self::C&lt;/code&gt;，不過用 &lt;code&gt;$this-&amp;gt;C&lt;/code&gt; 也可以，但是那樣的話用 &lt;code&gt;$a1-&amp;gt;getConstant()&lt;/code&gt; 會產生錯誤。總之，把 class constant 當做 static final 變數來使用&lt;/p&gt;</description></item><item><title>PostgreSQL 筆記</title><link>https://tomleesm.github.io/posts/2023/04/postgresql-cheatsheets/</link><pubDate>Mon, 24 Apr 2023 17:50:21 +0800</pubDate><guid>https://tomleesm.github.io/posts/2023/04/postgresql-cheatsheets/</guid><description>&lt;p&gt;之前都在用 MySQL，好奇隔壁棚的 PostgreSQL 有什麼不一樣，所以想玩玩看。講 PostgreSQL 的書相比 MySQL 很少，幸運的是最近發現一本「SQL 語法查詢入門」，使用的是 PostgreSQL，所以以下是這本書的筆記。&lt;/p&gt;
&lt;p&gt;資料庫、資料表和資料欄名稱如果要用引號，必須用雙引號，資料欄的值如果要用引號，必須用單引號。&lt;/p&gt;
&lt;h2 id="新增和管理資料庫"&gt;新增和管理資料庫&lt;/h2&gt;
&lt;p&gt;在 Linux 執行以下指令，用 PostgreSQL 預設的管理員帳號執行 psql 管理程式&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u postgres psql
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;新增使用者和資料庫，並設定權限&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- 新增使用者，同時設定密碼
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;使用者名稱&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WITH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PASSWORD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;密碼&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- 新增使用者和擁有者
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DATABASE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;資料庫名稱&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;OWNER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;使用者名稱&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- 設定使用者對資料庫有完整權限
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;GRANT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ALL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;PRIVILEGES&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DATABASE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;資料庫名稱&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;使用者名稱&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="psql"&gt;psql&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 測試使用者能否登入&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;psql -U 使用者名稱 -d 資料庫名稱 -h 127.0.0.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 使用指定的資料庫和使用者執行 test.sql 儲存的 SQL，然後離開 psql&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;psql -U 使用者名稱 -d 資料庫名稱 -h 127.0.0.1 -f test.sql
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 顯示 psql 所有指令&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="se"&gt;\?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 更改連線的資料庫、使用者&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="se"&gt;\c&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;onnect&lt;span class="o"&gt;]&lt;/span&gt; 資料庫名稱 使用者名稱
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 離開 psql&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="se"&gt;\q&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="select-子句執行順序"&gt;SELECT 子句執行順序&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;欄位清單&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;資料表&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;條件式&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;GROUP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;條件式&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;HAVING&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;條件式&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;條件式&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;&lt;code&gt;FROM&lt;/code&gt; 產生資料集合&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WHERE&lt;/code&gt; 過濾 &lt;code&gt;FROM&lt;/code&gt; 產生的集合&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GROUP BY&lt;/code&gt; 彙整 &lt;code&gt;WHERE&lt;/code&gt; 過濾後的集合&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HAVING&lt;/code&gt; 過濾 &lt;code&gt;GROUP BY&lt;/code&gt; 彙整的集合&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SELECT&lt;/code&gt; 轉換過濾與彙集過的集合（通常是透過彙整函式）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ORDER BY&lt;/code&gt; 排序 &lt;code&gt;SELECT&lt;/code&gt; 轉換後的集合&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;(上述順序和說明來自 Effective SQL 中文版 P. 122，有稍加修改)&lt;/p&gt;</description></item><item><title>使用 API Blueprint 寫文件</title><link>https://tomleesm.github.io/posts/2023/04/api-blueprint-cheatsheets/</link><pubDate>Mon, 24 Apr 2023 17:50:21 +0800</pubDate><guid>https://tomleesm.github.io/posts/2023/04/api-blueprint-cheatsheets/</guid><description>&lt;p&gt;&lt;a href="https://apiblueprint.org"&gt;API Blueprint&lt;/a&gt; 是一種 markdown 語法的擴充，用來寫 RESTful API 文件&lt;/p&gt;
&lt;h2 id="工具"&gt;工具&lt;/h2&gt;
&lt;p&gt;API Blueprint 官網有列出許多工具，推薦網站&lt;a href="https://apiary.io"&gt;Apiary&lt;/a&gt;。免費註冊後就能在線上編輯文件，左右對照 Markdown 和預覽結果，對於屬性有完整支援。&lt;/p&gt;
&lt;p&gt;Aglio 則用來把 Markdown 轉成 HTML，安裝與使用方法如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 在 Debian 11 上安裝&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 先安裝 Node.js&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install curl build-essential
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -sL https://deb.nodesource.com/setup_16.x &lt;span class="p"&gt;|&lt;/span&gt; sudo bash -
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install nodejs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;node -v
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm -v
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 使用 npm 全域安裝&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo npm install -g aglio
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 也可以用 yarn 安裝&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 安裝 yarn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install curl gnupg
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg &lt;span class="p"&gt;|&lt;/span&gt; sudo apt-key add -
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;deb https://dl.yarnpkg.com/debian/ stable main&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /etc/apt/sources.list.d/yarn.list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install yarn
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;yarn --version
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 使用 yarn 全域安裝&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo yarn global add aglio
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;接著編輯好 markdown 檔案，例如 example.md，然後執行 &lt;code&gt;aglio -i example.md -o example.html&lt;/code&gt; ，轉換成 example.html。可以執行 &lt;code&gt;aglio&lt;/code&gt; 指令看看參數有哪些。可以使用 &lt;code&gt;aglio -i example.md -s -h 0.0.0.0 -p 8000&lt;/code&gt; 產生即時預覽。&lt;/p&gt;</description></item></channel></rss>