Flask學習之旅–數據庫

一、寫在前面

  在Web開發中,數據庫操作是很重要的一部分,因為網站的很多重要信息都保存在數據庫之中。而Flask在默認情況下是沒有數據庫、表單驗證等功能的,但是可以用Flask-extension為Web應用添加這些功能。

 

二、Flask SQLite

  SQLite是一款輕型的數據庫,是遵守ACID的關係型數據庫管理系統。由於Python對SQlite有內置的支持,因此在Flask應用程序中和SQLite進行交互是比較容易的。

  首先需要創建一個SQLite數據庫“user.db”,並在其中創建一張用戶表。代碼如下:

1 import sqlite3 2 
3 
4 conn = sqlite3.connect("user.db") 5 print("Connected!") 6 
7 conn.execute("CREATE TABLE USER(username TEXT, password TEXT, EMAIL TEXT)") 8 print("Table created successfully!") 9 conn.close()

  這裏就不貼HTML代碼了,就是一個註冊頁面,在註冊的時候會將用戶輸入的用戶名、密碼和郵箱傳到後台。在app.py中需要導入sqlite3模塊,然後連接前面創建的user.db,在建立連接之後創建一個游標對象,然後編寫SQL語句進行數據庫操作,整個過程都算是比較容易的。app.py中的代碼如下:

 1 from flask import Flask, render_template, request  2 import sqlite3 as sql  3 
 4 app = Flask(__name__)  5 
 6 
 7 @app.route('/register', methods=['GET', 'POST'])  8 def register():  9     if request.method == 'GET': 10         return render_template('register.html') 11     else: 12         msg = ""
13         try: 14             username = request.form["usr"] 15             password = request.form["pwd"] 16             email = request.form["email"] 17             print(username, password, email) 18             with sql.connect("user.db") as con: 19                 cur = con.cursor() 20                 cur.execute("INSERT INTO USER (username, password, email) VALUES (?,?,?)", 21  (username, password, email)) 22  con.commit() 23             msg = "註冊成功!"
24         except: 25  con.rollback() 26             msg = "註冊失敗!請重試!"
27         finally: 28  con.close() 29             return render_template('register.html', msg=msg) 30 
31 
32 if __name__ == '__main__': 33     app.run()

 

三、Flask SQLAlchemy

  Flask-SQLAlchemy是Flask擴展,它將對SQLAlchemy的支持添加到Flask應用程序中。在Flask Web應用程序中使用原始SQL對數據庫執行CRUD操作可能很繁瑣,不過SQLAlchemy 為應用程序開發人員提供了SQL的全部功能和靈活性。它是一個對數據庫的抽象,讓開發者不用這些編寫SQL語句,而是使用其提供的接口去操作數據庫,這其中涉及到一個非常重要的思想:ORM(Object Relation Mapping,對象關係映射),主要的功能是實現模型對象到關係型數據庫數據的映射。說白了就是使用通過對象去操作數據庫。

1.Flask-SQLAlchemy安裝

  使用pip install flask-sqlalchemy進行安裝。不過在安裝的時候可能會出現如下錯誤:

pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host=’files.pythonhosted.org’, port=443): Read timed out.

  這是因為在下載python庫的時候,由於國內網絡原因,導致python包的下載速度非常慢,查看pip 文檔,只要在 pip的時候控制超時即可, 具體參數為 –default-timeout=100, 後面的時間可以自己指定。因此可以用如下命令進行下載安裝:

pip install –default-timeout=100 flask-sqlalchemy

2.Flask-SQLAlchemy配置

  從此模塊導入SQLAlchemy類,創建一個Flask應用程序對象併為要使用的數據庫設置URI的代碼如下:

from flask_sqlalchemy import SQLAlchemy


app = Flask(__name__)

# URI的格式為:用戶名:密碼@ip地址:端口號(默認可以不寫)/數據庫名
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql://root:qwer1234@localhost/flask"

3.配置的時候可能出現的問題及解決辦法

1)ModuleNotFoundError: No module named ‘MySQLdb’

解決辦法:

  使用pymysql模塊,URI改為:

app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:qwer1234@localhost/flask"

2)Warning: (1366, “Incorrect string value: ‘\\xD6\\xD0\\xB9\\xFA\\xB1\\xEA…’ for column ‘VARIABLE_VALUE’ at row 481”)

解決辦法:

  改用mysql-connector,使用pip install mysql-connector下載安裝,URI改為:

app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+mysqlconnector://root:qwer1234@localhost/flask"

3)sqlalchemy.exc.NotSupportedError: (mysql.connector.errors.NotSupportedError) Authentication plugin ‘caching_sha2_password’ is not supported

解決辦法:

  出現這個錯誤是因為MySQL8.0採用了Use Strong Password Encryption for Authentication即強密碼加密,而mysql.connector的引擎不支持caching_sha2_password的加密格式,所以解決思路有如下幾種:

  (1)重裝MySQL,在Authentication Method中選擇第二項(重裝比較麻煩,我就沒有嘗試):

  (2)在client端,將加密格式選擇成mysql_native_password,命令如下(個人嘗試后無效):

ALTER user ‘root’@’localhost’ IDENTIFIED WITH mysql_native_password BY ‘root’

  (3)最後一種是我自己摸索出來的,就是在URI設置的時候加上一個參數auth_plugin並設置為mysql_native_password:

app.config[‘SQLALCHEMY_DATABASE_URI’] = “mysql+mysqlconnector://root:qwer1234@localhost/flask?auth_plugin=mysql_native_password”

4.Flask-SQLAlchemy的基本操作

1) 常用查詢過濾器:

  過濾器得到的還只是一些對象,需要使用執行器來獲取真正的數據。

filter(): 把過濾器添加到原查詢上,返回一個新查詢,需要使用模型類名去獲取字段來進行比較;

filter_by():把等值(只能使用=比較操作)過濾器添加到查詢上,返回一個新查詢;

order_by():根據指定條件對查詢結果進行排序,返回一個新查詢;

group_by():根據指定條件對原查詢結果進行分組,返回一個新查詢。

2.)常用查詢執行器

all():以列表的形式返回查詢的所有結果;

first():返回查詢的第一個結果;

first_or_404():同first(), 只不過如果沒有找到的話,返回404錯誤;

get():返回指定主鍵對應的行;

get_or_404():返回指定主鍵對應的行,如不存在,返回404錯誤;

count():返回查詢結果的數量;

paginate():返回一個Paginate對象,包含指定範圍內的結果。

3.)查詢條件

startswith('xx'):查詢以xx開頭的所有數據;

endswith('xx'):查詢以xx結尾的所有數據;

not_():取反;

and_():返回and()條件滿足的所有數據;

or_():返回or()條件滿足的所有數據。

5.使用示例

  app.py中代碼如下:

 1 from flask_sqlalchemy import SQLAlchemy
 2 import mysql.connector
 3 
 4 
 5 app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+mysqlconnector://root:qwer1234@localhost/flask?auth_plugin=mysql_native_password"
 6 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
 7 app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
 8 
 9 
10 # 獲取SQLAlchemy實例對象
11 db = SQLAlchemy(app)

  然後新建一個model.py,編寫如下代碼進行測試:

 1 from app import db
 2 
 3 
 4 # 創建模型對象
 5 class User(db.Model):
 6     __tablename__ = "users"
 7     id = db.Column(db.Integer, primary_key=True)
 8     username = db.Column(db.String(16), unique=True)
 9     password = db.Column(db.String(16))
10     email = db.Column(db.String(32), unique=True)
11 
12     def __repr__(self):
13         return '<User %r>' % self.username
14 
15 
16 # 1.創建表
17 db.create_all()
18 print("Created Successfully!")
19 
20 # 2.增加記錄
21 usr1 = User()
22 usr1.id = 1
23 usr1.username = "wang"
24 usr1.password = "wangwang"
25 usr1.email = "wang@163.com"
26 usr2 = User(id=2, username="yang", password="yang", email="yang@163.com")
27 db.session.add(usr1)
28 print("Add usr1")
29 db.session.add(usr2)
30 print("Add usr2")
31 db.session.commit()
32 
33 # 3.查詢記錄,注意查詢返回對象,如果查詢不到返回None
34 users1 = User.query.all()  # 查詢所有
35 print(users1)
36 print("User Count:", len(users1))
37 
38 # 4.刪除
39 user = User.query.get(1)
40 db.session.delete(user)
41 print("Delete usr1")
42 db.session.commit()
43 
44 users2 = User.query.all()  # 查詢所有
45 print(users2)
46 print("User Count:", len(users2))

  運行結果如下所示:

Created Successfully!
Add usr1
Add usr2
[<User ‘wang’>, <User ‘yang’>]
User Count: 2
Delete usr1
[<User ‘yang’>]
User Count: 1

 

【精選推薦文章】

自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

.NET中擴展方法和Enumerable(System.Linq)

LINQ是我最喜歡的功能之一,程序中到處是data.Where(x=x>5).Select(x)等等的代碼,她使代碼看起來更好,更容易編寫,使用起來也超級方便,foreach使循環更加容易,而不用for int..,linq用起來那麼爽,那麼linq內部是如何實現的?我們如何自定義linq?我們這裏說的linq不是from score in scores  where score > 80 select score;而是System.Linq哦。了解Ling之前先要了解擴展方法,因為linq的實質還是擴展方法。

擴展方法

擴展方法使你能夠向現有類型“添加”方法,而無需創建新的派生類型、重新編譯或以其他方式修改原始類型。 擴展方法是一種特殊的靜態方法,但可以像擴展類型上的實例方法一樣進行調用。 

例如:

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static int WordCount(this string str)
        {
            return str.Split(new char[] { ' ', '.', '?' }, 
                             StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }   
}
//添加引用
using ExtensionMethods;  
//使用
string s = "Hello Extension Methods";  
int i = s.WordCount();  

微軟擴展方法建議

微軟MSDN上的建議:通常,建議只在不得已的情況下才實現擴展方法,並謹慎地實現。只要有可能,都應該通過創建從現有類型派生的新類型來達到這一目的。

擴展方法建議

1. 當功能與擴展類型最相關時,可以考慮使用擴展方法。
2. 當對第三方庫進行擴充的時候,可以考慮使用擴展方法。
3. 當您不希望將某些依賴項與擴展類型混合使用時,可以使用擴展方法來實現關注點分離。
4. 如果不確定到底使用還是不使用擴展方法,那就不要用。

擴展方法是C#語言的一個很好的補充,她使我們能夠編寫更好,更容易讀的代碼,但是也應該小心使用,不恰當的使用擴展方法可能導致可讀性降低,使測試困難,容易出錯。

System.Linq

System.Linq用起來那麼好,她內部是如何實現的,當然是查看源碼了。

Where源碼

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
    if (source == null) throw Error.ArgumentNull("source");
    if (predicate == null) throw Error.ArgumentNull("predicate");
    if (source is Iterator<TSource>) return ((Iterator<TSource>)source).Where(predicate);
    if (source is TSource[]) return new WhereArrayIterator<TSource>((TSource[])source, predicate);
    if (source is List<TSource>) return new WhereListIterator<TSource>((List<TSource>)source, predicate);
    return new WhereEnumerableIterator<TSource>(source, predicate);
}

這個方法就是一個擴展方法,對數據進行了處理,具體的處理都是在對象中的MoveNext中

public override bool MoveNext() {
    if (state == 1) {
        while (index < source.Length) {
            TSource item = source[index];
            index++;
            if (predicate(item)) {
                current = item;
                return true;
            }
        }
        Dispose();
    }
    return false;
}

可以看出就是一個循環處理,如果你覺得還是不清楚,可以看WhereIterator方法

static IEnumerable<TSource> WhereIterator<TSource>(IEnumerable<TSource> source, Func<TSource, int, bool> predicate) {
    int index = -1;
    foreach (TSource element in source) {
        checked { index++; }
        if (predicate(element, index)) yield return element;
    }
}

這下明白了,linq就是擴展方法,對數據進行處理,返回所需要的數據,知道了原理之後,可以寫自己的linq擴展方法了。
我想寫一個帶有控制台輸出的Where擴展方法

public static IEnumerable<TSource> WhereWithLog<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    if (source == null)
    {
        throw new ArgumentNullException("source", "不能為空");
    }

    if (predicate == null)
    {
        throw new ArgumentNullException("predicate", "不能為空");
    }


    int index = 0;
    foreach (var item in source)
    {
        Console.WriteLine($"Where item:{item},結果:{predicate(item)}");
        if (predicate(item))
        {
            yield return item;
        }
        index++;
    }
}

實現一個打亂數據的擴展方法,這裏的方法用了約束,只能是值類型。

public static IEnumerable<T> ShuffleForStruct<T>(this IEnumerable<T> source) where T : struct
{
    if (source == null)
        throw new ArgumentNullException("source", "不能為空");

    var data = source.ToList();
    int length = data.Count() - 1;
    for (int i = length; i > 0; i--)
    {
        int j = rd.Next(i + 1);
        var temp = data[j];
        data[j] = data[i];
        data[i] = temp;
    }

    return data;
}

到此為止是不是覺得Enumerable中的方法也就是那麼回事,沒有那麼難,我也可以實現。

【精選推薦文章】

智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

想知道網站建置、網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計及後台網頁設計

帶您來看台北網站建置台北網頁設計,各種案例分享

廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

TDD(測試驅動開發)死了嗎?

01、前言

很早之前,曾在網絡上見到過 TDD 這 3 個大寫的英文字母,它是 Test Driven Development 這三個單詞的縮寫,也就是“測試驅動開發”的意思——聽起來很不錯的一種理念。

其理念主要是確保兩件事:

  • 確保所有的需求都能被照顧到
  • 在代碼不斷增加和重構的過程中,可以檢查所有的功能是否正確

但後來很長一段時間里,都沒再聽過 TDD 的消息。有人說,TDD 已經死了,給出的意見如下:

1)通常來說,開發人員不應該在沒有失敗的測試用例下編寫代碼——這似乎是合理的,但是它可能導致過度測試。例如,為了保證一行生產代碼的正確性,你不由得寫了 4 行測試代碼,這意味着一旦這一行生產代碼需要修改,你也得修改那 4 行測試代碼。

2)為了遵循 TDD 而寫的代碼,容易進入一個誤區:代碼是為了滿足測試用的,而忽略了實際需求。

02、TDD 到底是什麼?

不管 TDD 到底死了沒有,先讓我們來回顧一下 TDD 到底是什麼。

TDD 的基本思想就是在開發功能代碼之前,先編寫測試代碼。也就是說在明確要開發某個功能后,首先思考如何對這個功能進行測試,並完成測試代碼的編寫,然後編寫相關的代碼滿足這些測試用例。然後循環進行添加其他功能,直到完成全部功能的開發

TDD 的基本過程可以拆解為以下 6 個步驟:

1) 分析需求,把需求拆分為具體的任務。

2) 從任務列表中取出一個任務,並對其編寫測試用例。

3) 由於沒有實際的功能代碼,測試代碼不大可能會通過(紅)。

4) 編寫對應的功能代碼,儘快讓測試代碼通過(綠)。

5) 對代碼進行重構,並保證測試通過(重構)。

6) 重複以上步驟。

可以用下圖來表示上述過程。

03、TDD 的實踐過程

通常情況下,我們都習慣在需求分析完成之後,儘快地投入功能代碼的編寫工作中,之後再去調用和測試。

而 TDD 則不同,它假設我們已經有了一個“測試用戶”了,它是功能代碼的第一個使用者,儘管功能代碼還不太完善。

當我們站在“測試用戶”的角度去寫測試代碼的時候,我們要考慮的是,這個“測試用戶”該如何使用功能代碼呢?是通過一個類直接調用方法呢(靜態方法),還是構建類的實例去調用方法呢(實例方法)?這個方法如何傳參呢?方法如何命名呢?方法有返回值嗎?

有了測試代碼后,我們開始編寫功能代碼,並且要以最快地速度讓測試由“紅”變為“綠”,可能此時的功能代碼很不優雅,不過沒關係

當測試通過以後,我們就可以放心大膽的對功能代碼進行“重構”了——優化原來比較醜陋、臃腫、性能偏差的代碼。

接下來,假設我們接到了一個開發需求:

汪汪隊要到小鎮冒險島進行表演,門票為 99 元,冒險島上唯一的一個程序員王二需要開發一款可以計算門票收入的小程序。

按照 TDD 的流程,王二需要先使用 Junit 編寫一個簡單的測試用例,測試預期是:銷售一張門票的收入是 99 元。

public class TicketTest {

    private Ticket ticket;

    @Before
    public void setUp() throws Exception {
        ticket = new Ticket();
    }

    @Test
    public void test() {
        BigDecimal total = new BigDecimal("99");

        assertEquals(total, ticket.sale(1));
    }

}

為了便於編譯能夠順利通過,王二需要一個簡單的 Ticket 類:

public class Ticket {

    public BigDecimal sale(int count) {
        return BigDecimal.ZERO;
    }

}

測試用例運行結果如下圖所示,紅色表示測試沒有通過:預期結果是 99,實際結果是 0。

那接下來,王二需要快速讓測試通過,Ticket.sale() 方法修改后的結果如下:

public class Ticket {

    public BigDecimal sale(int count) {
        if (count == 1) {
            return new BigDecimal("99");
        }
        return BigDecimal.ZERO;
    }

}

再運行一下測試用例,結果如下圖所示,綠色表示測試通過了:預期結果是 99,實際結果是 99。

綠了,綠了,測試通過了,到了該重構功能代碼的時候了。99 元是個魔法数字,至少應該聲明成常量,對吧?

public class Ticket {
    private final static int PRICE = 99;

    public BigDecimal sale(int count) {
        if (count == 1) {
            return new BigDecimal(PRICE);
        }
        return BigDecimal.ZERO;
    }

}

重構完后再運行一下測試用例,確保測試通過的情況下,再增加幾個測試用例,比如說門票銷量為負數、零甚至一千的情況。

public class TicketTest {

    private Ticket ticket;

    @Before
    public void setUp() throws Exception {
        ticket = new Ticket();
    }

    @Test
    public void testOne() {
        BigDecimal total = new BigDecimal("99");

        assertEquals(total, ticket.sale(1));
    }

    @Test(expected=IllegalArgumentException.class)
    public void testNegative() {
        ticket.sale(-1);
    }

    @Test
    public void testZero() {
        assertEquals(BigDecimal.ZERO, ticket.sale(0));
    }

    @Test
    public void test1000() {
        assertEquals(new BigDecimal(99000), ticket.sale(1000));
    }

}

銷量為負數的時候,王二希望功能代碼能夠拋出異常;銷量為零的時候,功能代碼的計算結果應該為零;銷量為一千的時候,計算結果應該為 99000。

重新運行一下測試用例,結果如下圖所示:

有兩個測試用例沒有通過,那麼王二需要繼續修改功能代碼,調整如下:

public class Ticket {
    private final static int PRICE = 99;

    public BigDecimal sale(int count) {
        if (count < 0) {
            throw new IllegalArgumentException("銷量不能為負數");
        }

        if (count == 0) {
            return BigDecimal.ZERO;
        }

        if (count == 1) {
            return new BigDecimal(PRICE);
        }

        return new BigDecimal(PRICE * count);
    }

}

再運行一下測試用例,發現都通過了。又到了重構的時候了,銷量為零、或者大於等於一的時候,代碼可以合併,於是重構結果如下:

public class Ticket {
    private final static int PRICE = 99;

    public BigDecimal sale(int count) {
        if (count < 0) {
            throw new IllegalArgumentException("銷量不能為負數");
        }

        return new BigDecimal(PRICE * count);
    }

}

重構結束后,再運行測試用例,確保重構后的代碼依然可用。

04、最後

從上面的實踐過程可以得出如下結論:

TDD 想要做的就是讓我們對自己的代碼充滿信心,因為我們可以通過測試代碼來判斷這段代碼是否正確無誤。

也就是說,TDD 流程比較關鍵的一環在於如何寫出有效的測試代碼,這裡有 4 個原則可以參考:

1)測試過程應該盡量模擬正常使用的過程。

2)應該盡量做到分支覆蓋。

3)測試數據應該盡量包括真實數據,以及邊界數據。

4)測試語句和測試數據應該盡量簡單,容易理解。

注意,這 4 個原則不僅適用於 TDD,同樣適用於任何流程下的單元測試。

最後,我想說的是,不管 TDD 有沒有死,TDD 都不是銀彈,不可能適合所有的場景,但這不應該成為我們拒絕它的理由。

 

【精選推薦文章】

如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

想要讓你的商品在網路上成為最夯、最多人討論的話題?

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師"嚨底家"!!

Emotify 為網站加入心情投票按鈕,依照使用者喜好推薦相關文章

記得幾年前開始流行在新聞網站或部落格加入「心情」功能,讓讀者在閱讀內容後可以快速點選想法投票,不用輸入留言來提高使用者參與度,其實是非常聰明的作法。如果你也想在網站內加入心情按鈕,但又苦無技術開發能力,本文介紹的 Emotify 或許可滿足需求,同時它也是一項完全免費的服務,支援一般網站、WordPress、Tumblr 和 Ghost 等平台。

Emotify 是一個提供心情按鈕功能的免費服務,如同在網站加上 DISQUS 留言、LinkWithin 相關文章,只要在網站內放置一段程式碼,Emotify 就能在你的網站或部落格運作心情按鈕功能,同時在點選後依照心情提供讀者更多相關文章,增加停留在網站的時間和黏性。

Emotify 是收集使用者反應及意見回饋的方法,一般來說,我們很難得到使用者真實心情體驗,即使透過意見調查或口頭詢問,也不容易在短時間內獲得全面的想法。Emotify 讓這些數據更加容易收集整合,亦能運用分析來判斷使用者偏好的內容類型。

網站名稱:Emotify
網站鏈結:https://www.goemotify.com/

使用教學

STEP 1

開啟 Emotify 網站後,點選「Sign Up」來免費註冊帳號,註冊時依序填入姓名、Email 和密碼就能完成註冊,別忘記至信箱收取驗證信才能完成啟用。

STEP 2

登入 Emotify 網站後,我們需要先將自己的網站加入平台,填入網站名稱、網址,從底下選擇網站分類及描述,點選「Continue」即可。

最後,Emotify 會將程式碼顯示給你,你可以從頁面中選取平台,例如:WordPress、Tumblr 或 Ghost,若你使用的平台不在網站列出範圍,那麼直接使用 Web / Js 程式碼吧!

STEP 3

以下我使用 WordPress 來進行 Emotify 安裝範例,我們先從外掛功能來搜尋 Emotify,將它安裝到網站裡,同時啟用這項外掛。

最後,把 Emotify 給我們的 API Key 輸入到 Emotify 設定頁面,儲存後就安裝完成。

STEP 4

隨即可以在文章頁面下方看到 Emotify 心情按鈕功能,如下圖所示。

其實它的設計還算簡單,可惜目前沒有中文化,要不應該更能提高中文使用者點選意願。依照讀者閱讀心情,分成:Amazing、Elated、Great、Happy、Inspired 和 Excited 六種,如果不知道這些單字的意思,透過表情圖案應該也能略知一二。

點選「More」會出現更多可以選擇的表情圖案,例如:Love、Happy、LOL、Surprised、Sad 和 Angry,表情非常可愛。當收集到足夠的資料和網址時,使用者在點選心情後會在下方推薦其他可以閱讀的相關內容,也算是能有效提升使用者參與度及停留時間的方法。

STEP 5

點選任一表情圖案後,其他圖案會變成灰色顯示,同時出現一個快速輸入想法(或建議)的小對話框,如果你覺得點選心情按鈕不太夠,想要稍微抒發想法,下方允許輸入 160 個字。

STEP 6

最後,網站管理者可以從 Emotify 控制台來查看目前點選心情按鈕的人數。

從分析頁面找到每一篇文章被按下的心情按鈕頻率、分佈情形和分別按了那些心情,就網站經營觀點來說,Emotify 能幫助我們確定文章或頁面內容是否符合使用者喜好,或者應該要如何調整方向來滿足大多數人喜好,這裡收集到資訊有非常多可以分析思考的面向。

當前 Facebook 僅提供讓網站使用按讚和分享按鈕,不知道什麼時候會把表情符號功能開放讓一般網站或部落格使用呢?雖然好像有點在半開玩笑,但未嘗不是提高參與度或收集使用者想法的好辦法,趁著還沒開放前可先使用 Emotify 替代,讓你的網站增添一些動態功能。

  • 按一下以分享至 Facebook(在新視窗中開啟)
  • 分享到 Twitter(在新視窗中開啟)
  • 分享到 LinkedIn(在新視窗中開啟)
  • 分享到 Pinterest(在新視窗中開啟)
  • 分享到 Pocket(在新視窗中開啟)

相關文章

本站聲明:網站內容來源免費資源網路社群https://free.com.tw,如有侵權,請聯繫我們,我們將及時處理

【精選推薦文章】

自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

Social Warfare 輕量美觀的社群分享按鈕

如果你是免費資源網路社群長期讀者,應該注意到我不時在調整網站各項設定,其中大家最熟悉、也最常使用的就屬社交網站按鈕吧!許多人習慣在看到不錯內容時,順手點擊頁面分享按鈕來把網址轉載到其他社群,早期我使用過 AddThis,後來覺得它功能太過強大,拖延到網站載入速度,改採 SumoMe 結合多種免費社群按鈕,讓網站流量成長 20% 分享按鈕整合平台。SumoMe 最近換了全新計價方式,對於流量較大的網站來說是不小的負擔,因此我又尋尋覓覓找到另外一款也很棒的分享按鈕替代方案。

Social Warfare 是一款 WordPress 社群分享按鈕外掛程式,在國外小有名氣,但台灣就比較少看到網站使用。Social Warfare 最大賣點是程式碼非常輕量,載入速度飛快無比,不會造成網站載入延遲等問題,因此可以替換掉原先放在網站內的社群網站官方按鈕。

外掛內建功能正合我意,例如可以快速自訂要顯示的分享按鈕、分享數計算,以及最重要的是支援響應式設計(Responsive),因此無論在什麼樣的裝置螢幕瀏覽,按鈕都會自動調整到最好的大小,避免因為尺寸不合而破壞網站版面,也能在行動裝置上正常顯示。

Social Warfare 在上個月推出全新 2.0 大改版,整體控制台煥然一新,除此之外,也加入更多功能來改善原有外掛不足。不過最大的消息是從 2.0 開始在 WordPress 官方外掛資料庫上架!現在即使沒有付費,也能使用 Social Warfare 部分功能,讓它在你的網站上正常顯示分享按鈕功能。

Social Warfare 依照網站數量提供不同規格的授權費用,單一網站每年為 $29 USD,如果一次購買五個網站可以降到 $27 USD($135 USD),最優惠的價格是一次購買十個網站授權,單一網站可優惠至 $25 USD($250 USD)。

雖然 Social Warfare 免費版功能受限,但並不影響一般使用,沒有付費依然能把它加入自己 WordPress 網站,常用按鈕例如 Facebook、Twitter、Google+、Pinterest 和 LinkedIn 等皆內建於外掛中,也能顯示分享次數和總分享數,設定浮動分享按鈕。

網站名稱:Social Warfare
網站鏈結:https://warfareplugins.com/

使用教學

STEP 1

開啟你的 WordPress 外掛控制台,點選左側的「外掛 -> 安裝外掛」,接著在右上角搜尋框輸入 Social Warfare 搜尋。

Social Warfare 是 WordPress 外掛功能,唯有使用 WordPress.org 自行架站才能夠於控制台內下載、安裝新外掛,不適用於 WordPress.com。

出現 Social Warfare 後,點選右上角的「立刻安裝」,就能把它下載到自己網站。

STEP 2

安裝後,左側選單會多出一個「Social Warfare」設定鏈結,點選後開啟外掛控制台。預設情況下會有五個常見常用的社交網路按鈕,拖曳到 Active 區塊為啟用狀態,其他按鈕則不允許免費版使用,但其實這五個按鈕已經非常足夠。

STEP 3

將視窗往下拖曳,把 Share Counts(分享計數器)功能開啟,就能在分享按鈕上顯示該鏈結或文章被分享的次數。

STEP 4

另一個很重要的部分是從下方的「Position Share Buttons」功能來設定按鈕顯示位置,跟一般外掛不同的是 Social Warfare 把顯示位置設定的非常單純簡單,只有顯示於內容上方或下方、不顯示或同時顯示四種選項,建議把右側的 Side Floating Buttons 開啟(後面會介紹這功能)。

STEP 5

別忘記在 Social Identity 裡設定一下你的 Twitter、Pinterest、Facebook 鏈結或帳號,當使用者點選分享按鈕時,就會自動帶入你指定的帳號,藉此提高能見度。

STEP 6

Social Warfare 按鈕設計確實蠻簡單優雅,且平面化風格無論對於那一種網站來說都非常合適,如果你有打開分享按鈕計數器,可能不會立刻就跑出數字,必須給 Social Warfare 一些時間來抓取數據和快取(以避免過度抓取資料而被第三方網站封鎖)。

當你把網頁寬度縮小,模擬成在手機、平板電腦上顯示時,Social Warfare 按鈕也會自動縮小到適當寬度,這就是前面提到的支援響應式設計(Responsive)特色。

Social Warfare 最讓我喜愛的是當你把頁面往下拖曳時,分享按鈕會自動固定於頁面的上方或下方(從控制台的 Floating Share Buttons 可以調整顯示位置),對於提高使用者分享率來說會有顯著提升!而且按鈕固定在頁面下方比較不會造成畫面空間浪費。

很久沒有寫文章向大家推薦 WordPress 外掛功能了,其實這一路以來接觸過無數外掛,很少讓我興起寫文章念頭的(說不定只是因為功能太多不知道要從那裡開始介紹…),但在使用 Social Warfare 後,我認為團隊很用心在開發,致力於提供更好的分享按鈕功能,因此決定寫篇文章介紹來推薦給所有 WordPress 使用者,希望大家喜歡!

透過本文推薦鏈結(Affiliate Link)購買 Social Warfare 能讓我獲得一些回饋,我會非常感謝你的,但如果你想直接連回官方網站而不用推薦鏈結,請點選這裡。

  • 按一下以分享至 Facebook(在新視窗中開啟)
  • 分享到 Twitter(在新視窗中開啟)
  • 分享到 LinkedIn(在新視窗中開啟)
  • 分享到 Pinterest(在新視窗中開啟)
  • 分享到 Pocket(在新視窗中開啟)

相關文章

本站聲明:網站內容來源免費資源網路社群https://free.com.tw,如有侵權,請聯繫我們,我們將及時處理

【精選推薦文章】

智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

想知道網站建置、網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計及後台網頁設計

帶您來看台北網站建置台北網頁設計,各種案例分享

廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

100HUB 免費台灣虛擬主機,採Plesk控制台

有不少朋友問我,這幾年好像很少介紹免費虛擬主機?原因很簡單,因為不容易找到我認為足夠穩定、可靠的選項,尤其虛擬主機維持長時間營運實屬不易,通常要有其他營利項目才足以打平開支,對於沒有先經過一段時間「洗禮」的服務我不輕易推薦給讀者。當然要架站的話我認為還是去付費租用虛擬主機會比較可靠一些,例如我在 WordPress 教學文件就曾經推薦過五個虛擬主機服務,價格都不貴,而且有不滿意全額退款保證。

本文要介紹的免費虛擬主機服務 100HUB 並不是新服務,除了提供免費但有廣告的虛擬主機外,也有不同客戶族群適用的主機方案,包括 VPS、網域名稱及 SSL 憑證等項目。如果你不想那麼快付費,想先試試看使用 WordPress 架站是否合乎你的需求,那麼免費的廣告型虛擬主機或許是可考慮的選擇。

100HUB「威利 100 專業主機」是我在 CloudFlare 合作夥伴找到的少數台灣主機商,因為有合作關係,支援 Railgun 功能,100hub.com 客戶搭配 CloudFlare 時將可以獲得更快的連線速度!可惜的是免費虛擬主機不支援 Railgun,但因為主機位於日本,從台灣或亞洲任何國家連線速度都是相當順暢的。

100HUB 免費虛擬主機分成兩種,一種是免費試用 14 天,另一種是廣告型免費主機,但能永久使用,而現今大部分虛擬主機服務都已有不滿意全額退款保證,有時間限制的試用方案倒不那麼吸引人,我會建議使用廣告型空間(沒有時間限制),如果你只是想要練習架站或個人部落格,這個方案規格已相當充裕。

廣告型免費主機提供 300 MB 空間,每月有 6 GB 流量限制,主機位於日本 GMO 東京機房,從台灣連線速度很不錯,對於小型個人網站或部落格來說已經非常充裕。不過必須要提醒的是 100HUB 採用 Plesk 控制台,而不是大部分使用者熟悉的 cPanel,一樣也有提供中文介面,若不是非 cPanel 不用的話倒是沒什麼影響。

接下來我簡單介紹 100HUB 免費日本虛擬主機的註冊申請方式,以及如何在 Plesk 快速架設一個自己的 WordPress 網站。

網站名稱:100HUB 威利100專業主機
網站鏈結:https://100hub.com/

使用教學

申請 100HUB 免費日本虛擬主機教學

STEP 1

開啟 100HUB.com 網站後,從首頁的規格方案中點選「免費」下方「立即申請」,接著會看到三種免費產品,其中有兩種是免費試用 14 天,最後一種為「廣告型免費主機」,我們點選廣告型免費主機最下方的「馬上申請」鏈結。

由於註冊新的網域名稱或移轉(Transfer)都必須付費,因此我們選擇使用 100HUB 提供的免費域名,網址結尾為 .100hub.net,設定一個你要使用的名稱。

STEP 2

如果你選擇的名稱還沒有被佔用,就會跳出支付結帳畫面,價格確認為 0 元,沒問題的話點選右側「結帳」綠色按鈕來跳到下一個畫面。

STEP 3

接著要填寫你的個人資料和帳單資訊,100hub.com 規定使用者必須填寫正確且可供驗證的資料,這部分記得花點時間填寫,如果亂填或資料有誤可能無法通過審核。

STEP 4

註冊後,你的 100HUB 免費帳戶狀態會顯示為「確認中」,大約要等待數小時,站方審核後才會開通、啟用帳號。

使用虛擬主機快速架設 WordPress

STEP 1

當 100hub.com 審核完你的免費虛擬主機申請,就會以 Email 通知,從主機商的控制台可以取得包括使用者名稱、主機名稱、IP 位址和進入 PLESK 後台的登入鏈結。

STEP 2

下圖就是 HUB100 免費虛擬主機使用的 PLESK 控制台介面,怎麼看起來好像跟印象中差了很多?無論如何,控制台就是一個網站最核心的部分,從這裡可以進行主機設定、應用程式安裝、網域名稱管理、Email、資料庫、統計等功能,因此要妥善保存你的帳號密碼。

點選 PLESK 控制台左側選單的「應用程式」,找到「WordPress」後按下「安裝」,當然你也可以選擇要安裝的 WordPress 版本(建議還是以安裝最新版為主)。

STEP 3

選好後就會以自動化工具來安裝、設定 WordPress,其實 WordPress 本身安裝介面設計已經非常簡單,甚至可以在五分鐘以內架設好一個網站,不過如果使用自動化安裝程式的話幾乎不用做任何設定,可以算是最快的安裝法。

安裝後,PLRSK 會顯示你的網址、安裝位置、帳號密碼,建議把「自動更新」功能開啟以增加安全性,未來當有任何新的版本釋出,WordPress 就會自動更新檔案,以保持你的網站在最新、最安全狀態。

STEP 4

進入你的 WordPress 網站後,點選側邊欄右下角的「登入」,以 PLESK 提供的帳號密碼即可登入控制台。或者你可以先試著體驗一下 100HUB 免費虛擬主機的速度,我在台灣連線速度是還蠻快的,換頁也不會有感覺卡卡的問題。

因為 100HUB 免費虛擬主機是會顯示廣告的,因此左下角會有一個 LOGO 圖案,但廣告只是一個鏈結,不會侵入你的內容部分,倒也還可以接受。

如果你覺得自動化安裝工具設定的帳號密碼很難記憶,記得在登入後從「帳號」功能來新增新的管理員帳戶,這麼做除了可增加安全性外,亦能將最初建立的帳號移除,同時熟悉一下 WordPress 帳戶權限設定。

開始享受你的網站吧!

當然,免費虛擬主機不是只能安裝 WordPress,你也可以安裝其他開放原始碼程式,或者拿來單純做為 HTML 網頁託管使用,並沒有侷限於單一功能,不過還是要提醒,如果有任何重要內容,不建議直接放到免費主機上,因為無法保證網站能夠持續運作,若要使用免費主機,也記得要時時備份網站資料,以免發生任何狀況而讓資料遺失無法救回喔!

  • 按一下以分享至 Facebook(在新視窗中開啟)
  • 分享到 Twitter(在新視窗中開啟)
  • 分享到 LinkedIn(在新視窗中開啟)
  • 分享到 Pinterest(在新視窗中開啟)
  • 分享到 Pocket(在新視窗中開啟)

相關文章

本站聲明:網站內容來源免費資源網路社群https://free.com.tw,如有侵權,請聯繫我們,我們將及時處理

【精選推薦文章】

如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

想要讓你的商品在網路上成為最夯、最多人討論的話題?

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師"嚨底家"!!

Highlight Bookmark Manager 為網站加入劃重點、討論和書籤功能

如果你還有印象,三個月前我介紹過「HiLight 為網站加入螢光筆標記、群組討論及收藏分享內容等互動式功能」服務,只要在網站加入程式碼,輕鬆整合劃重點、摘要和留言討論、收藏內容等工具,對於內容或媒體網站來說非常實用!尤其想讓內容能更有效被討論或分享使用,就無須花大錢開發不知道好不好用的功能,HiLight 是一項最快最方便的解決方案,而且完全免費。

HiLight 由台灣團隊開發製作,相較於一些類似的國外服務來說,更符合中文使用者的操作習慣以及對中文字元支援。近期針對 WordPress 開發了全新外掛「Highlight Bookmark Manager」,已在 WordPress 官方外掛目錄上架,如果你是自己架站的朋友,可參考以下教學快速將 HiLight 整合到自己網站。

簡單來說,當安裝完「Highlight Bookmark Manager」外掛後,網站左下角會多出三個新按鈕,分別是筆記、討論和書籤功能。使用者只要選取網頁內的文字段落就能輕鬆劃上螢光筆高亮效果(Highlight),加入自己的觀點,這麼一來將有助於拉長使用者停留在網站時間,亦提供了一個更好的討論渠道,也能將內容再次分享至其他社群平台。

網站名稱:Highlight Bookmark Manager
網站鏈結:http://www.hilight.cc/installation/wordpress

使用教學

STEP 1

HiLight 網站首頁提供兩種安裝方法,如果你不是使用 WordPress 架站的話,可以直接建立帳號來取得程式碼,將它加入網站就能使用;若你的網站是 WordPress,那麼就更簡單方便了,直接從 HiLight 官方網站的 WordPress 外掛頁面來下載安裝即可。

另一種安裝方式是登入你的 WordPress 控制台,點選左側「外掛 -> 安裝外掛」,接著在右上角輸入 hilight 搜尋。

搜尋結果第一個就是「Highlight Bookmark Manager」,點選右上角「立即安裝」就能將它下載、安裝到 WordPress。從 WordPress 4.6 版開始,安裝及啟用外掛和佈景主題變得更快更簡潔了,直接在原頁面就能下載、啟用,節省時間。

STEP 2

安裝後 Highlight Bookmark Manager 還無法運作,我們必須先註冊以取得自己網站專屬的 API 資訊,將網頁拉到最下方,就能找到連接至 Highlight Bookmark 註冊鏈結。

STEP 3

點選「Log in With Facebook」以你的 Facebook 帳戶登入註冊。

輸入你的網站網址、名稱後,點選「Submit」為你的網站建立一個新帳戶。

最後就能獲取 Highlight Bookmark Manager 的 Web Id 和 Web Secret,這兩項資訊非常重要,記得不要將它外流出去,以避免安全問題。

STEP 4

回到 Highlight Bookmark Manager 外掛的設定選項,將 Web Id 和 Web Secret 兩項數值填入後點選「Submit」,出現確認訊息就完成連接和基本設定。

STEP 5

設定好 Highlight Bookmark Manager 後,我們就可以回到網站前台來測試功能,試著複製文章任一段文字內容,會跳出 HiLight 工具列,能夠劃線做筆記,或者開啟討論留言功能。

使用 Highlight Bookmark 來保存內容也是一個相當方便的作法,可惜它目前僅能在安裝這項工具的網站使用,跟一般我們可能使用過筆記工具不同(大部分都是 Google Chrome 或 Firefox 外掛),使用時一樣得先登入你的 Facebook 帳戶,用於存取你保存或討論的相關內容記錄。

我相當推薦 HiLight 的原因是它的劃線及討論功能非常好用,而且可以取代的免費服務並不多(尤其又是中文服務相對更少),若你覺得只提供文章迴響或 Facebook 留言框無法讓讀者聚焦於內容討論的話,我認為 Highlight Bookmark Manager 更是一個不可多得的網站工具!

STEP 6

如同前面提到的,使用 HiLight 標記內容後,還能透過分享功能將它傳送給其他人,或者分享至 Facebook、Twitter、Google+ 等社群網站!不用再擔心其他人找不到討論功能因而使寶貴的意見石沈大海,

本篇文章側重於 Highlight Bookmark Manager 外掛在 WordPress 網站的安裝及設定教學,沒有對 HiLight 有更深入的報導或討論,若你想更詳細了解這項功能,可參考我之前寫的 HiLight 為網站加入螢光筆標記、群組討論及收藏分享內容等互動式功能。

整體來說,這項服務非常深得我心,無論在網站或影片介紹甚至程式方面都具備中英文介面,看得出 HiLight 積極向外發展的野心,期待未來能有更多發展空間。

  • 按一下以分享至 Facebook(在新視窗中開啟)
  • 分享到 Twitter(在新視窗中開啟)
  • 分享到 LinkedIn(在新視窗中開啟)
  • 分享到 Pinterest(在新視窗中開啟)
  • 分享到 Pocket(在新視窗中開啟)

相關文章

本站聲明:網站內容來源免費資源網路社群https://free.com.tw,如有侵權,請聯繫我們,我們將及時處理

【精選推薦文章】

自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

WordPress 無敵架站手冊:架站新手都想擁有,參加活動免費帶回家

免費資源網路社群跟著 WordPress 一起長大,可以這麼說,我在 2006 年接觸 WordPress 後隨即就架設了第一個部落格,迄今十年,也就是大家正在瀏覽的網站。這些年持續不斷在 WordPress Taiwan 正體中文社群盡自己最大努力,除了程式中文語系維護,我也嘗試翻譯、撰寫部分教學文件以及在外掛功能上推動中文化工作,本著自己也有在使用就順手做一下,讓後來加入的人可以少碰一些問題的想法,我做得很開心。

這幾年台灣使用 WordPress 架站的朋友越來越多,全世界市佔率超越 25%(數據來自 W3Tech),到處都能看到 WordPress 蹤跡,想架設網站幾乎沒有第二個選項。但回到台灣書店一望,WordPress 書籍仍舊寥寥可數(當然相較於幾年前來說已經算活躍許多),即使網路上已有豐富的教學文件,卻沒有一本非常完整的中文手冊。

對於學習 WordPress 架站的人來說,想從頭到尾、穩紮穩打很難找到學習路徑,於是我這幾年就興起想要寫一本由淺入深、全面的 WordPress 工具書,恰巧得知英國出版商 Packt Publishing 的《WordPress 4.x Complete》一書,二話不說就決定將它翻譯成中文書,讓想學 WordPress 架站的朋友有個更完整的參考資料。

《WordPress 無敵架站手冊》是一本從 WordPress 介紹、入門、安裝操作,到進階開發外掛、佈景主題及小工具等主題皆有涵蓋的完整手冊!後半章節還會教你如何利用 WordPress 建立非網誌型態網站。

雖然無法在有限篇幅內詳細說明所有範圍,但讀者可將本書做為學習的起點,從基礎延伸出去,繼續學習。對於有心想要了解 WordPress 架站的朋友來說,這是一本易於閱讀及上手的工具書,也希望透過這本書讓你認識更方便、安全可靠的免費開放原始碼架站程式 WordPress。

如何購買這本書,網上購書更優惠

如果你對架站有興趣,或者對於 WordPress 好奇、有興趣、想學習甚至是希望搭建一個自己的個人網站或部落格,你可以在實體店面或從網路通路買到這本書,我僅在文章內提供幾個購書鏈結,透過 Google 搜尋可以找到更多管道。

購書鏈結:http://www.books.com.tw/products/0010730008 (博客來)

久違的抽獎活動,還是要免費送書

若你一路以來都有在關注或追蹤免費資源網路社群的文章,依照慣例我都會提供一些贈品來送讀者,感謝博碩文化贊助本次贈書。

活動方式一如往昔,只要到免費資源網路社群 Facebook 粉絲專頁按個讚、在本文下方留言,就有機會在免費得到《WordPress 無敵架站手冊》!我們會在活動結束後抽出幸運讀者,在最短時間內將新書寄到您手上。

STEP 1

前往免費資源網路社群 Facebook 按個讚,相信大家都已經按過(也請多多幫我們宣傳分享,謝謝);如果你有使用其他社群網站,例如 Twitter、Google+,也一併將免費資源網路社群加入追蹤。網站右側還有一些免費資源網路社群使用的社群服務。

STEP 2

在本文下方留言(或直接在粉絲頁面同一則貼文留言)回覆以下文字:

WordPress 無敵架站手冊:架站新手都想擁有,參加活動免費帶回家

這樣就可以參加抽獎活動,是不是非常簡單呢?

活動時間五天,請多多分享轉貼

如果方便的話,也歡迎將本文鏈結分享、轉貼到你的 Facebook 或其他網站。若活動夠踴躍,我們也會視情況增加更多贈書名額喔!我會在下週三(9/28)抽出幸運的朋友,屆時在本文更新及 Facebook 等社群網站公告得獎情形,請大家把握這次難得機會多多支持!

得獎名單(9/28 晚間 22:00 更新)

本次活動一共有 816 位讀者參加,扣掉重複留言,以「粉絲團留言抽籤小助手」小工具隨機抽取 10 位留言者贈送新書《WordPress 無敵架站手冊》一本,幸運得獎的朋友名單如下(依照抽獎結果順序排列):

黃楚翔、王凱蓓、Yu-Wei Chen、Stella Lin、Cheng Lin、尹翠軒、盧嘉皓、黃豊益、胡倫、黃謙。

請幸運中獎的讀者儘速與 Pseric 聯繫,我也會到留言下方 tag 通知你,直接私訊告知我收件人資料即可。確認完畢就會陸續將熱騰騰的新書寄到你們手上囉!本書已在各大書局、網路書店上架,有興趣的朋友也能直接從網上購得,謝謝大家熱烈參與支持本次活動!

為了公平起見,下方是本次抽獎影片紀錄:

  • 按一下以分享至 Facebook(在新視窗中開啟)
  • 分享到 Twitter(在新視窗中開啟)
  • 分享到 LinkedIn(在新視窗中開啟)
  • 分享到 Pinterest(在新視窗中開啟)
  • 分享到 Pocket(在新視窗中開啟)

相關文章

本站聲明:網站內容來源免費資源網路社群https://free.com.tw,如有侵權,請聯繫我們,我們將及時處理

【精選推薦文章】

智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

想知道網站建置、網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計及後台網頁設計

帶您來看台北網站建置台北網頁設計,各種案例分享

廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

Cloudflare 免費 WordPress 外掛教學,一鍵為網站快速套用最佳化設定


(Photo credit: TechCrunch via Visualhunt / CC BY)

最近 CloudFlare 在台灣網路圈吵蠻兇的,起因是 CloudFlare 八月在自家網站公布服務在全世界各地頻寬支出成本(參考資料:Bandwidth Costs Around the World),其中點名的六家超高成本 ISP 業者在亞洲就有台灣中華電信 HiNet 及韓國電信,相較於歐洲或北美支出的頻寬成本來說多出 15 倍!CloudFlare 為了提出抗議,更大動作將連線到使用 CloudFlare 服務網站的中華電信使用者導向頻寬成本較低的美國西岸節點。

其實連到美西頻寬夠大,速度倒也不是非常糟,畢竟很多網站都選擇放在開銷較低的國外機房,那麼這段距離對於台灣使用者開啟網站的速度並沒有太大影響。但恰巧中華電信近期發生海底電纜異常,尖峰時段連線壅塞造成很多網站無法打開,才會有好像取消台灣節點造成網站變慢的問題。

撇開這些狀況不說,我還是推薦架站時搭配 CloudFlare 提供的免費 CDN 來加速網站連線速度,同時遏止任何可能的攻擊或安全問題,類似服務還有 Incapsula,但沒有它來得這麼全面(目前 CF 節點數也是同類服務之冠)。

關於 CloudFlare 使用教學我在「CloudFlare 架站者必備免費 CDN、DNS 託管服務設定教學,網站載入加速、節省流量防止惡意攻擊」一文有完整說明,若你是使用 WordPress 架站,我建議你務必安裝全新 CloudFlare 外掛,它為 WP 使用者提供更多功能。

早先 WordPress 的 CloudFlare 外掛只有解析 IP 功能,讓無法在控制台迴響顯示使用者真實 IP 位址的問題得以解決;近期 CloudFlare 外掛更新,將設定選項帶進 WordPress 控制台,往後將可以在控制台進行一些基本的設定或操作,也能查看分析報表。

網站名稱:CloudFlare for WordPress
網站鏈結:https://tw.wordpress.org/plugins/cloudflare/

使用教學

STEP 1

登入 WordPress 控制台後,點選左側選單的「外掛 -> 安裝外掛」,右上角填入 CloudFlare 會跳出相關結果,第一個就是來自 CloudFlare 官方的外掛功能,點選「立即安裝」即可將它下載安裝到網站。

在外掛列表中將 CloudFlare 啟用,設定裡就會多一個 CF 設定頁面。

STEP 2

不過要在控制台使用 CloudFlare 功能,必須要連結到你 CF 帳戶,驗證方法是 Email 加上你的 API 密鑰,這組密鑰在哪呢?只要開啟 CloudFlare 控制台並點選右上角的 My Settings 就能找到(網頁下方的 Global API Key,點選 View API Key 就會顯示)。

這組密鑰非常重要,等同於你的密碼,切勿將它告訴其他人。

回到 WordPress 的 CloudFlare 設定頁面,輸入你的 CloudFlare 帳號(Email)及 API Key 就能成功串連,基本上登入畫面只需要設定一次,之後就不會再次出現。

STEP 3

接著會看到 CloudFlare 在全新 3.0 版加入的所有功能,介面也變得跟以前不同。

如果你剛開始接觸 CF,沒有太多時間來詳細研究各項設定,推薦你直接使用第一項設定的「Apply Default Settings」一鍵套用最適合網站效能的建議設定值,這也是此次更新後我認為最喜愛的功能。

STEP 4

CloudFlare 在新的 WordPress 外掛程式上已經加入清理快取(Purge Cache)自動化完整快取管理(Automatic Full Cache Management)功能,若開啟後當你更新網站選項時就會自動清理 CloudFlare 的快取內容。不過預設情況下其實不太需要打開,因為網站頁面並不會被 CloudFlare 快取,只有圖片等靜態元件才會。

STEP 5

另外,設定頁右上角的「Enable “Im Under Attack” Mode」是一項很特殊的功能,如果你認為你的網站正遭遇攻擊,或者有人想嘗試登入網站(例如使用暴力破解),點選後就能使網站獲得更高安全性的保護措施。

正常情況下並不建議開啟這項功能,因為很可能會使一般訪客在瀏覽時發生問題。

STEP 6

其他設定選項在「More Settings」可以找到,完整設定項目建議回到 CloudFlare 調整修改,外掛裡沒有涵蓋所有選項。但還是要補充一下,從 Analytics 裡可以看到 CF 端的分析圖表了!這也是此次更新中非常令人振奮的全新功能。

  • 按一下以分享至 Facebook(在新視窗中開啟)
  • 分享到 Twitter(在新視窗中開啟)
  • 分享到 LinkedIn(在新視窗中開啟)
  • 分享到 Pinterest(在新視窗中開啟)
  • 分享到 Pocket(在新視窗中開啟)

相關文章

本站聲明:網站內容來源免費資源網路社群https://free.com.tw,如有侵權,請聯繫我們,我們將及時處理

【精選推薦文章】

如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

想要讓你的商品在網路上成為最夯、最多人討論的話題?

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師"嚨底家"!!

Java集合 ArrayList原理及使用

ArrayList是集合的一種實現,實現了接口List,List接口繼承了Collection接口。Collection是所有集合類的父類。ArrayList使用非常廣泛,不論是數據庫表查詢,excel導入解析,還是網站數據爬取都需要使用到,了解ArrayList原理及使用方法顯得非常重要。

一. 定義一個ArrayList

//默認創建一個ArrayList集合
List<String> list = new ArrayList<>();
//創建一個初始化長度為100的ArrayList集合
List<String> initlist = new ArrayList<>(100);
//將其他類型的集合轉為ArrayList
List<String> setList = new ArrayList<>(new HashSet());

我們讀一下源碼,看看定義ArrayList的過程到底做了什麼?

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    /**
     * Default initial capacity.
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
     * Shared empty array instance used for empty instances.
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};

    /**
     * Shared empty array instance used for default sized empty instances. We
     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
     * first element is added.
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer. Any
     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     * will be expanded to DEFAULT_CAPACITY when the first element is added.
     */
    transient Object[] elementData; // non-private to simplify nested class access

    /**
     * The size of the ArrayList (the number of elements it contains).
     *
     * @serial
     */
    private int size;

    /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param  initialCapacity  the initial capacity of the list
     * @throws IllegalArgumentException if the specified initial capacity
     *         is negative
     */
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    /**
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection's
     * iterator.
     *
     * @param c the collection whose elements are to be placed into this list
     * @throws NullPointerException if the specified collection is null
     */
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }
}

其實源碼裏面已經很清晰了,ArrayList非線程安全,底層是一個Object[],添加到ArrayList中的數據保存在了elementData屬性中。

  • 當調用new ArrayList<>()時,將一個空數組{}賦值給了elementData,這個時候集合的長度size為默認長度0;

  • 當調用new ArrayList<>(100)時,根據傳入的長度,new一個Object[100]賦值給elementData,當然如果玩兒的話,傳了一個0,那麼將一個空數組{}賦值給了elementData;

  • 當調用new ArrayList<>(new HashSet())時,根據源碼,我們可知,可以傳遞任何實現了Collection接口的類,將傳遞的集合調用toArray()方法轉為數組內賦值給elementData;

注意:在傳入集合的ArrayList的構造方法中,有這樣一個判斷

if (elementData.getClass() != Object[].class),

給出的註釋是:c.toArray might (incorrectly) not return Object[] (see 6260652),即調用toArray方法返回的不一定是Object[]類型,查看ArrayList源碼

public Object[] toArray() {    return Arrays.copyOf(elementData, size);}

我們發現返回的確實是Object[],那麼為什麼還會有這樣的判斷呢?

如果有一個類CustomList繼承了ArrayList,然後重寫了toArray()方法呢。。

public class CustomList<E> extends ArrayList {
    @Override
    public Integer [] toArray() {
        return new Integer[]{1,2};
    };
    
    public static void main(String[] args) {
        Object[] elementData = new CustomList<Integer>().toArray();
        System.out.println(elementData.getClass());
        System.out.println(Object[].class);
        System.out.println(elementData.getClass() == Object[].class);
    }
}

執行結果:

class [Ljava.lang.Integer;
class [Ljava.lang.Object;
false

接着說,如果傳入的集合類型和我們定義用來保存添加到集合中值的Object[]類型不一致時,ArrayList做了什麼處理?讀源碼看到,調用了Arrays.copyOf(elementData, size, Object[].class);,繼續往下走

public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {    
    T[] copy = ((Object)newType == (Object)Object[].class)
        ? (T[]) new Object[newLength]
        : (T[]) Array.newInstance(newType.getComponentType(), newLength); 
    System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
    return copy;
}

我們發現定義了一個新的數組,將原數組的數據拷貝到了新的數組中去。

二. ArrayList常用方法

ArrayList有很多常用方法,add,addAll,set,get,remove,size,isEmpty等

首先定義了一個ArrayList,

List<String> list = new ArrayList<>(10);
list.add('牛魔王');
list.add('蛟魔王');
...
list.add('美猴王');

Object[] elementData中數據如下:

1. add(E element)

我們通過源碼來看一下add(“白骨精”)到底發生了什麼

public boolean add(E e) {
    ensureCapacityInternal(size + 1);
    // Increments modCount!!
    elementData[size++] = e;
    return true;
}

首先通過 ensureCapacityInternal(size + 1) 來保證底層Object[]數組有足夠的空間存放添加的數據,然後將添加的數據存放到數組對應的位置上,我們看一下是怎麼保證數組有足夠的空間?

private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

這裏首先確定了Object[]足夠存放添加數據的最小容量,然後通過 grow(int minCapacity) 來進行數組擴容

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

擴容規則為“數組當前足夠的最小容量 + (數組當前足夠的最小容量 / 2)”,即數組當前足夠的最小容量 * 1.5,當然有最大值的限制。

因為最開始定義了集合容量為10,故而本次不會進行擴容,直接將第8個位置(從0開始,下標為7)設置為“白骨精”,這時Object[] elementData中數據如下:

還有和add()類似的方法。空間擴容原理都是一樣,如:

add("鐵扇", 0); //將數組中的元素各自往後移動一位,再將“鐵扇”放到第一個位置上;

addAll(list..七個葫蘆娃); //將集合{七個葫蘆娃}放到”白骨精”后,很明顯當前數組的容量已經不夠,需要擴容了,不執行該句代碼了;

addAll(list..哪吒三兄弟, 4);//從第五個位置將“哪吒三兄弟”插進去,那麼數組第五個位置后的元素都需往後移動三位,數組按規則擴容為18。

指定了插入位置的,會通過rangeCheckForAdd(int index)方法判斷是否數組越界

2. set(int index, E element)

因為ArrayList底層是由數組實現的,set實現非常簡單,調用 set(8, "豬八戒") 通過傳入的数字下標找到對應的位置,替換其中的元素,前提也需要首先判斷傳入的數組下標是否越界。將“獼猴王”替換為“豬八戒”

public E set(int index, E element) {
    rangeCheck(index);
    E oldValue = elementData(index);
    elementData[index] = element;
    return oldValue;
}

//返回值“獼猴王”,當前數組中數據:

3. get(int index)

ArrayList中get方法也非常簡單,通過下標查找即可,同時需要進行了類型轉換,因為數組為Object[],前提是需要判斷傳入的數組下標是否越界。

public E get(int index) {
    rangeCheck(index);
    return elementData(index);
}
E elementData(int index) {
    return (E) elementData[index];
}

調用get(6)返回”哪吒“。

4. remove(int index)

首先說一下ArrayList通過下標刪除的方法,我們看一下源碼

public E remove(int index) {
    rangeCheck(index);
    modCount++;
    E oldValue = elementData(index);
    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index, numMoved);
    elementData[--size] = null; // clear to let GC do its work
    return oldValue;
}

通過源碼我們可以看到首先獲取了待刪除的元素,並最終返回了。其次計算了數組中需要移動的位數 size – index – 1,那麼很明顯我們可以得出待刪除的是最後一個元素的話,移到位數為0,否則移動位數大於0,那麼通過數組元素的拷貝來實現往前移動相應位數。

如remove(10),找到的元素為“美猴王”,那麼移動位數 = 12-10-1 = 1;此時將原本在第12個位置上(數組下標為11)的“白骨精”往前移動一位,同時設置elementData[11] = null;這裏通過設置null值讓GC起作用。

5. remove(Object o)

刪除ArrayList中的值對象,其實和通過下標刪除很相似,只是多了一個步驟,遍歷底層數組elementData,通過equals()方法或 == (特殊情況下)來找到要刪除的元素,獲取其下標,調用remove(int index)一樣的代碼即可。

public boolean remove(Object o) {
    if (o == null) {
        for (int index = 0; index < size; index++)
            if (elementData[index] == null) {
                fastRemove(index);
                return true;
            }
    } else {
        for (int index = 0; index < size; index++)
            if (o.equals(elementData[index])) {
                fastRemove(index);
                return true;
            }
    }
    return false;
}

6. 其他方法

size() : 獲取集合長度,通過定義在ArrayList中的私有變量size得到

isEmpty():是否為空,通過定義在ArrayList中的私有變量size得到

contains(Object o):是否包含某個元素,通過遍歷底層數組elementData,通過equals或==進行判斷

clear():集合清空,通過遍歷底層數組elementData,設置為null

三. 總結

本文主要講解了ArrayList原理,從底層數組着手,講解了ArrayList定義時到底發生了什麼,再添加元素時,擴容規則如何,刪除元素時,數組的元素的移動方式以及一些常用方法的用途,若有不對之處,請批評指正,望共同進步,謝謝!

【精選推薦文章】

自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"