Thao Trinh – Người thích tự do và lang thang như gió -
  • Trang chủ
  • Chuyện nghề
  • Đọc
  • Me
Thao Trinh – Người thích tự do và lang thang như gió -
Trang chủ
Chuyện nghề
Đọc
Me
  • Trang chủ
  • Chuyện nghề
  • Đọc
  • Me
Học nghề

Tạo ứng dụng blockchain đầu tiên với C#

thaotrinh.info__tao-ung-dung-blockchain-dau-tien-voi-c

Thông qua bài viết này mình sẽ hướng dẫn các bạn làm quen và hiểu thêm về công nghệ Blockchain.

Mục đích

– Tạo hệ thống Blockchain đơn giản nhất.
– Tạo hệ thống mining (poor of work) đơn giản.
– Khám phá thêm về Blockchain.

Kiến thức cần chuẩn bị: OOP, biết 1 ngôn ngữ hướng đội tượng.
Ok giờ xắn tay vào việc nào

Making the Blockchain.

Một blockchain là danh sách, chuỗi các khối (A blockchain is just a chain/list of blocks). Mỗi block trong blockchain sẽ chứa chữ ký số của nó, chữ ký số của khối trước nó và dữ liệu của khối (dữ liệu giao dịch là một ví dụ).

thaotrinh.info__tao-ung-dung-blockchain-dau-tien-voi-c

 

Hash = Digital Signature.

Mỗi khối không chỉ chứa mã hash của khối trước nó mà nó còn chứa mã hash của chính nó, được tính toán dựa trên mã hash của khối trước nó. Nếu dữ liệu khối trước đó bị thay đổi (khối A), việc này dẫn tới thay đổi mã hash của khối A, do mã hash được tính toán dựa trên data này. Việc này dẫn tới sự thay đổi mã hash của tất cả các khối trong chuỗi. Việc tính toán và so sánh giúp chúng ta phát hiện ra bất kì sự thay đổi nào trong blockchain.

Điều này có nghĩa là gì? – Nghĩa là khi thay đổi dữ liệu của 1 block thì sẽ dẫn tới thay đổi dữ liệu của rất rất nhiều block, và dãn tới thay đổi chain (break the chain).

Giờ chúng ta sẽ thừ bắt đầu xây dựng một hệ thống Blockchain đơn giản.

Tạo project đặt tên là NoobChain

Thêm class Block để xây dựng blockchain

class Block
{
        public String hash;
        public String previousHash;
        private String data; // Trong ví dụ này chúng ta chỉ lưu data là một thông báo.
        private long timeStamp;
        

        //Block Constructor.
        public Block(String data, String previousHash)
        {
            this.data = data;
            this.previousHash = previousHash;
            this.timeStamp = DatetimeHandle.GetTime();            
        }     

}

Như bạn thấy Block cơ bản của chúng ta chứa một chuỗi hash sẽ dùng để lưu chữ kí số. Một biến previousHash để lưu hash của khối trước nó, và dữ liệu của khối.

Bước tiếp theo chúng ta sẽ tiến hành tạo chữ ký số.
Tạo lớp HashSha256, áp dụng thuật toán sha256 để sinh chuỗi, với nội dung như sau:

class HashSha256
{
  public override string Hash(string strInput)
  {
    try
    {
      var crypt = new System.Security.Cryptography.SHA256Managed();
      var hash = new System.Text.StringBuilder();
      byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(strInput));
      foreach (byte theByte in crypto)
      {
        hash.Append(theByte.ToString("x2"));
      }
      return hash.ToString();
    }
    catch (Exception e)
    {
      throw e;
    }    
  }
}

Sau đó quay trờ lại lớp Block thêm và hàm tính mã hash

public String CalculateHash()
{
  HashSha256 sha256 = new HashSha256();
  String calculatedhash = sha256.Hash(
      previousHash +
      timeStamp.ToString()
      data);
  return calculatedhash;
}

 

.. và thêm hàm này vào contructor của lớp Block

public Block(String data, String previousHash)
{
  this.data = data;
  this.previousHash = previousHash;
  this.timeStamp = DatetimeHandle.GetTime();
  this.hash = CalculateHash(); // thêm hàm này vào cuối để chắc chắn các dữ liệu khác được init trước khi gọi hàm
}

Ok, giờ chúng ta thử kiểm tra lại công việc vừa làm xem…
Trong hàm Main của class program.cs chúng ta sẽ viết đoạn code để hiển thị chuỗi hash

Khối đầu tiên được gọi là genesis block, và vì nó không có khối phía trước nên ta sẽ gán previousHash của nó bằng 0

class Program
{       
  static void Main(string[] args)
  {
    Block genesisBlock = new Block("Hi im the first block", "0");
    Console.WriteLine("Hash for block 1 : " + genesisBlock.hash);

    Block secondBlock = new Block("Yo im the second block", genesisBlock.hash);
    Console.WriteLine("Hash for block 2 : " + secondBlock.hash);

    Block thirdBlock = new Block("Hey im the third block", secondBlock.hash);
    Console.WriteLine("Hash for block 3 : " + thirdBlock.hash);          

    Console.ReadLine();
  }
}

Output của chúng ta sẽ là 3 mã hash

thaotrinh.info__tao-ung-dung-blockchain-dau-tien-voi-c
Mỗi block giờ sẽ chứa chữ kí số được xây dựng trên thông tin của nó và chữ ký số của khối phía trước.
Để giống với khái niệm blockchain hơn, ta sẽ lưu trữ các block này trong List
Chỉnh sửa file program.cs như sau:

class Program
{
  public static List<Block> blockchain = new List<Block>();

  static void Main(string[] args)
  {
    blockchain.add(new Block("Hi im the first block", "0"));		
    blockchain.add(new Block("Yo im the second block",blockchain.ElementAt(blockchain.size()-1).hash)); 
    blockchain.add(new Block("Hey im the third block",blockchain.ElementAt(blockchain.size()-1).hash));

    string printBlockChain = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(blockchain);
    Console.WriteLine(printBlockChain);

    Console.ReadLine();
  }
}

Để sử dụng được JavaScriptSerializer thì các bạn làm như sau

Right click References and do Add Reference, then from Assemblies->Framework select System.Web.Extensions

Chạy lại ứng dụng và xem kết quả thử nhé mọi người 🙂

 

Kiểm tra tính toàn vẹn của blockchain.

Chúng ta sẽ viết phương thức IsChainValid() kiểu boolean trong file program.cs. Phương thức nãy sẽ loop qua tất cả các block trong chain và so sánh các chuỗi hash. Phương thức này sẽ cần kiểm tra biến hash so sánh nó với chuỗi hash được tính toán, và chỗi hash ở khối trước so sánh với biến previousHash. Uhm, nghe có vẻ phức tạp, thử nhìn code xem có dễ hiểu hơn không nào.

public static Boolean IsChainValid()
{
  Block currentBlock;
  Block previousBlock;

  //loop through blockchain to check hashes:
  for (int i = 1; i < blockchain.Count; i++)
  {
    currentBlock = blockchain.ElementAt(i);
    previousBlock = blockchain.ElementAt(i - 1);

    //compare registered hash and calculated hash:
    if (!currentBlock.hash.Equals(currentBlock.CalculateHash()))
    {
      Console.WriteLine("Current Hashes not equal");
      return false;
    }

    //compare previous hash and registered previous hash
    if (!previousBlock.hash.Equals(currentBlock.previousHash))
    {
      Console.WriteLine("Previous Hashes not equal");
      return false;
    }
  }
  return true;
}

Bất kì một thay đổi nào với mỗi block phương thức này sẽ trả về false.

Trên mạng lưới bitcoin, các nodes chia sẻ các blockchain và chuỗi hợp lệ dài nhất sẽ được châp nhận bởi hệ thống. Vậy nếu một hacker giả mạo một khối và tạo nên chuỗi blockchain mới cho mạng thì sao. Điều này là bất khả thi, vì sao? Giả sử hacker có thể xâm nhập và thay đổi một khối dữ liệu, điều này dẫn tới các dữ liệu tiếp theo của khối này cũng bị thay đổi. Vì vậy cần rất nhiều thời gian và sức mạnh tính toán để hacker có thể vượt hơn được so với sức mạnh tính toán của các thành viên còn lại trong hệ thống khi kết hợp.

Đào tiền ảo, cày sâu hay lướt sóng?

Lets start mining blocks!!!

Chúng ta sẽ yêu cầu minner tiến hành đào-coin bằng cách bắt họ phải thử các biến khác nhau trong block cho đến khi chuỗi hash bắt đầu với giá trị 0. Tại sao lại là 0?. Bạn có thể quy ước là bất cứ giá trị gì, tùy thuộc vào genesis hash của bạn. Trong trường hợp này chúng ta chọn 0.

Tiếp theo chúng ta thêm biến nonce trong hàm CalculateHash(), và thêm hàm MineBlock() như sau:

class Block
{
  public String hash;
  public String previousHash;
  private String data; //our data will be a simple message.
  private long timeStamp; //as number of milliseconds since 1/1/1970.
  private int nonce = 0;

  //Block Constructor.
  public Block(String data, String previousHash)
  {
    this.data = data;
    this.previousHash = previousHash;
    this.timeStamp = DatetimeHandle.GetTime();
    this.hash = CalculateHash();
  }

  public String CalculateHash()
  {
    HashSha256 sha256 = new HashSha256();
    String calculatedhash = sha256.Hash(
        previousHash +
        timeStamp.ToString() +
        nonce.ToString() + 
        data);
    return calculatedhash;
  }

  public void MineBlock(int difficulty)
  {
    var str = new String(new char[difficulty]);
    String target = new String(new char[difficulty]).Replace('\0', '0'); //Create a string with difficulty * "0" 
    while (!hash.Substring(0, difficulty).Equals(target))
    {
      nonce++;
      hash = CalculateHash();
    }
    Console.WriteLine("Block Mined!!! : " + hash);
  }
}

Phương thức MineBlock() truyền vào tham số difficulty kiểu int để quy định độ khó của thuật toán. Các bạn có thể thay đổi tham số này để kiểm tra tốc độ đào-coin khi chạy chương trình. Ở ví dụ này mình khuyến khích các bạn đặt ở mức 4-6 cho việc testing. Ex, Hiện tại độ khó của Litecoin là khoảng 442,592, khá kinh khủng.

Chúng ta thêm biến difficulty vào lớp program.cs:

public static int difficulty = 5;

Tiếp đó chúng ta cập nhật lớp program.cs, gọi hàm MineBlock() cho mỗi block mới. Phương thức IsChainValid() cũng được gọi sau khi đào được coin :D.

class Program
{
  public static List<Block> blockchain = new List<Block>();
  public static int difficulty = 5;

  static void Main(string[] args)
  {
    blockchain.Add(new Block("Hi im the first block", "0"));
    Console.WriteLine("Trying to Mine block 1... ");
    blockchain.ElementAt(0).MineBlock(difficulty);

    blockchain.Add(new Block("Yo im the second block", blockchain.ElementAt(blockchain.Count - 1).hash));
    Console.WriteLine("Trying to Mine block 2... ");
    blockchain.ElementAt(blockchain.Count - 1).MineBlock(difficulty);

    blockchain.Add(new Block("Hey im the third block", blockchain.ElementAt(blockchain.Count - 1).hash));
    Console.WriteLine("Trying to Mine block 3... ");
    blockchain.ElementAt(blockchain.Count - 1).MineBlock(difficulty);

    Console.WriteLine("\nBlockchain is Valid: " + IsChainValid());
    string printBlockChain = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(blockchain);
    Console.WriteLine(printBlockChain);

    Console.ReadLine();
  }

  public static Boolean IsChainValid()
  {
    Block currentBlock;
    Block previousBlock;

    //loop through blockchain to check hashes:
    for (int i = 1; i < blockchain.Count; i++)
    {
      currentBlock = blockchain.ElementAt(i);
      previousBlock = blockchain.ElementAt(i - 1);

      //compare registered hash and calculated hash:
      if (!currentBlock.hash.Equals(currentBlock.CalculateHash()))
      {
        Console.WriteLine("Current Hashes not equal");
        return false;
      }

      //compare previous hash and registered previous hash
      if (!previousBlock.hash.Equals(currentBlock.previousHash))
      {
        Console.WriteLine("Previous Hashes not equal");
        return false;
      }
    }
    return true;
  }
}

Chạy thử và xem kết quả nhé

thaotrinh.info__tao-ung-dung-blockchain-dau-tien-voi-c
Ối zồi ôi tôi đào được coin rồi này 😀

Kết

Một blockchain giả mạo sẽ không thể bắt kịp chuỗi dài hơn và hợp lệ trừ khi chúng có tốc độ tính toán lớn hơn tất cả các nút khác trong mạng của bạn kết hợp. Một máy tính lượng tử trong tương lai hay gì đó (người ngoài hành tinh?)

Demo

https://github.com/kumochan/Blockchain-Sample-01

August 18, 2017by thaotrinh
Học nghề

Cấu hình Virtual Host trong XAMPP

Virtual Host (Vhost) là một cấu hình trong Apache để cho phép nhiều domain cùng chạy trên một máy chủ. Để dễ hình dung hơn khi các bạn chạy webapps ở môi trường phát triển sẽ có url localhost:1234. Giờ ta có thể làm url trở nên thân thiện hơn bằng các chuyển nó thành dạng giống domain: thaotrinh.dev:1234
Trong bài viết này mình chỉ muốn chia sẻ với các bạn còn lạ lẫm về Vhost cách để cấu hình một Virtual Host trong Windows, ở đây mình sử dụng XAMPP làm môi trường phát triển.

Các bạn có thể tải XAMPP từ trang chủ: https://www.apachefriends.org

Sau khi tiến hành cài đặt xong các bạn mở file httpd.conf tại đường dẫn <thu_muc_cai_dat_xampp>\apache\conf\httpd.conf

Mình cài xampp ở đây E:\xampp\apache\conf\httpd.conf

Tìm tới dòng

# Virtual hosts
# Include conf/extra/httpd-vhosts.conf

Bỏ comment ở dòng Include đi. Nội dung sau khi bỏ comment

# Virtual hosts
Include conf/extra/httpd-vhosts.conf

 

OK tới đây file httpd.conf sẽ nhúng thêm file httpd-vhosts.conf khi khởi chạy.
Tiếp theo mở file httpd-vhosts.conf lên (file nằm trong đường dẫn conf/extra/httpd-vhosts.conf)
Thêm đoạn code này vào

<VirtualHost *:8080>
  DocumentRoot "E:/www/wordpress/thaotrinh"
  ServerName thaotrinh.dev
  <Directory "E:/www/wordpress/thaotrinh">
    Options Indexes FollowSymLinks Includes ExecCGI
    AllowOverride All
    Order allow,deny
    Allow from all
  </Directory>
</VirtualHost>

Giải thích thêm
<VirtualHost></VirtualHost> Đây là cặp thẻ báo hiệu mở đầu và kết thúc của một khai báo về Vhost. Có một lưu ý nhỏ là nếu bạn nào đổi port của Apache (8080,81,v.v…) thì cũng phải đổi số 80 theo port các bạn chuyển sang nhé. Ở đây mình đã đổi port của Apache thành 8080. Các bạn chỉnh sửa thành port tương ứng cấu hình của mình.

DocumentRoot Đây là từ khóa khai báo đường dẫn của thư mục sẽ được gọi khi người dùng truy cập vào domain được cấu hình. Đường dẫn này có thể nằm ở bất kỳ một phân vùng nào. Mình đặt website của mình theo đường dẫn E:/www/wordpress/thaotrinh

ServerName Chính là domain mà bạn muốn đặt (gõ thaotrinh.dev:8080 trên url là nó ra websites :D)

<Directory></Directory> Đây là cặp thẻ dùng để cấp quyền truy cập cho thư mục nếu thư mục không được cấp quyền sẽ gặp lỗi 403 khi các bạn cố gắng truy cập. Đường dẫn thư mục của bạn có thể là một regular expression. Nếu các bạn không rõ về Regex thì các bạn có thể dùng đường dẫn thư mục giống với khai báo trong DocumentRoot hoặc tham khảo thêm tại: http://httpd.apache.org/docs/2.4/en/mod/core.html#directory

Các bạn khởi động lại Apache bằng cách là khởi động phần mềm XAMPP Control Panel dòng nếu dòng Apache đang running thì các bạn stop và start lại, còn nếu đang ở chế độ tắt rồi thì các bạn chỉ cần start là được.

Ok vậy là bạn đã cấu hình xong về phần của Apache giờ chỉ việc đăng ký DNS cho domain của bạn nữa là mọi việc hoàn tất.

Các bạn mở file C:\Windows\System32\drivers\etc\hosts bằng notepad hoặc bất kỳ trình editor nào. Thêm vào cuối file và lưu lại. Nếu bạn không lưu được file hosts thì nhớ tắt tình năng readonly và thử chạy lại bằng mode Administrator nhé.

127.0.0.1 thaotrinh.dev

Khi các bạn gõ địa chỉ thaotrinh.dev:8080 thì máy sẽ ưu tiên tìm địa chỉ IP của domain đó trong file hosts của hệ điều hành trước tiên.

Nếu không có thì nó sẽ đi tìm địa chỉ IP của domain này thông qua các DNS Server trên Internet. Vì bạn đã khai báo trong file hosts nên nó sẽ sử dụng địa chỉ IP được khai báo trong đó luôn. Ở đây địa chỉ IP 127.0.0.1 trỏ về chính máy đang truy cập (chính là máy của bạn – còn nếu cấu hình trên server thì đó chính là bản thân máy server luôn). Bạn có thể sử dụng dài IP từ 127.0.0.1 -> 127.255.225.254 đây là dải IP trỏ về máy của bạn (Nguyên dải luôn chứ không phải chỉ là 127.0.0.1 nhé).

Giờ các bạn mở trình duyệt và gõ vào thanh địa chỉ thay thế dòng localhost xấu xí bằng một domain của riêng bạn. http://thaotrinh.dev thaotrinh.dev cũng có thể là bangkieu.tv, hanoi.buffalow(chấm local. chấm canh, chấm mắm, hay chấm bất kì thứ gì bạn thích nhé, chỉ cần nhớ là đã khai báo trong ServerName và file host là được).

Tổng kết

Việc sử dụng Virtual Host có vài lợi ích sau.

  • Bạn có thể truy cập vào bất kỳ thư mục code nào mà không cần phải copy vào htdocs trong XAMPP.
  • Nếu bạn dùng folder code ở một phân vùng khác thì bạn không cần phải lo lắng backup lại folder code mỗi lần cài lại windows.
  • Nhìn có vẻ nguy hiểm hơn :v

Các bạn cũng có thể cấu hình Vhost với WAMP, APPServer, USBServer các cấu hình cũng không khác nhiều lắm. Vì tất cả các phần mềm này đều dùng Apache, Mysql và PHP. Vhost là một tình năng của Apache chứ không phải của XAMPP nên phần mềm nào dùng Apache thì đều có thể cấu hình Vhost theo cách tương tự, điểm khác biệt chỉ là khác về nơi đặt file httpd.conf. Chúc các bạn thành công.

May 18, 2017by thaotrinh
Học nghề

Cài đặt và cấu hình Apache, MySQL trên macos

OSX 10.10 Yosemite được cài đặt sẵn Apache 2.4. Để khởi động web server, các bạn chỉ việc mở Terminal (/Applications/Utilities/Terminal) và gõ:

sudo apachectl start

Tương tự khi muốn restart và stop Apache

sudo apachectl stop

sudo apachectl restart

Sau khi start Apache, bạn có thể mở trình duyệt lên và gõ thử localhost sẽ xuất hiện thông báo It works!

Chú ý: Nếu bạn không thể truy cập được http://localhost thì bạn sẽ cần thêm alias vào file /etc/hosts: 127.0.0.1 localhost. Mặc định thì nó đã có sẵn (Vào Finder. Gõ tổ hợp phím: Command + Shift + G. Khi cửa sổ tìm kiếm hiện ra ta gõ: “/etc/” và nhần Go)

Document Root
Điều đầu tiên chúng ta muốn làm sẽ là thay đổi Document Root cho Apache. Đây là folder mà Apache sẽ tìm kiếm file để phục vụ. Mặc định thì Document Root được thiết lập ở /Library/WebServer/Documents. Chúng ta sẽ thay đổi nó về thư mục home – thư mục user của bạn. Để thực hiện điều này, chúng ta cần thay đổi file /etc/apache2/httpd.conf. Do đây là file được sở hữu bởi root nên bạn sẽ cần thêm sudo để có thể thay đổi được file. Ở đây mình dùng vim, bạn có thể dùng các editor khác như sublime text hay nano nếu thích.

sudo vi /etc/apache2/httpd.conf

 

Vim edit httpd.config file
Vim edit httpd.config file

Tìm từ DocumentRoot, bạn sẽ thấy dòng sau:

DocumentRoot "/Library/WebServer/Documents"

Thay đổi đường dẫn thành folder dưới user của bạn. Ở đây tôi dùng thư mục webroot/wordpress

DocumentRoot "/Users/your_user/webroot/wordpress"

Bạn cũng cần thay đổi đường dẫn ở trong thẻ <Directory>

<Directory "/Users/your_user/webroot/wordpress">

Ở ngay trong block của <Directory> bạn sẽ thấy AllowOverride, hãy thay đổi nó thành như sau:

AllowOverride All

DocumentRoot-config-vim

User & Group
Bây giờ Apache đã được thiết lập để trỏ tới thư mục /webroot/wordpress trong thư mục home của bạn. Tuy nhiên chúng ta vẫn có một vấn đề, đó là mặc định apache sẽ chạy dưới user _www và group _www. Điều này sẽ dẫn tới các vấn đề liên quan tới permisssion khi truy cập các file trong thư mục home. Chúng ta sẽ cần thay đổi chúng thành user mà bạn đang dùng và group staff. Vẫn ở trong file httpd.conf, bạn tìm 2 thiết lập User và Group và thay đổi chúng:

User your_user
Group staff

Đến đây chúng ta có thể save lại file httpd.conf. Gõ :wq và enter

Sau khi chỉnh sửa file httpd.conf thì tất nhiên bạn sẽ cần restart lại apache để cập nhật các thiết lập mới:

sudo apachectl restart

Bây giờ bạn cần tạo thư mục /webroot/wordpress ở trong thư mục home (your_user) của bạn. Ở trong thư mục /webroot/wordpress, chúng ta sẽ tạo thêm 1 file index.html với nội dung đơn giản: <h1>Hello Apache!!!</h1>.

Bây giờ hãy mở http://localhost bằng trình duyệt để kiểm tra xem nội dung chúng ta vừa viết có hiện ra không nhé. Nếu không bạn cần phải kiểm tra lại tất cả các bước vừa làm ở trên để chắc chắn mình đã thao tác đúng.

Vậy là chúng ta đã cấu hình và chạy được Apache trên Mac OS. Tiếp theo mình sẽ cùng các bạn tiếp tục cài đặt MySQL và PHP để bắt đầu code 😉

Cài đặt MySQL

Tải về MySQL tại http://dev.mysql.com/downloads/mysql/ (mình đề xuất tải bản DMG Archive), sau đó cài đặt (Lưu ý các bạn nên ghi nhớ mật khẩu default của user root khi cài đặt). Mở System Preferences, bạn sẽ thấy xuất hiện MySQL như hình:

cai-dat-mysql-01

Hãy bấm vào đó và chọn Start MySQL Server.

cai-dat-mysql-02

 

Trở lại terminal và gõ lần lượt các lệnh sau

export PATH=${PATH}:/usr/local/mysql/bin

mysql -u root -p

Bước tiếp theo các bạn nhập password của user root lúc cài đặt.

Nếu mọi thứ đều ổn các bạn sẽ nhận được thông tin cài đặt mysql

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 62
Server version: 5.7.18

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

Ok fine. Ở đây có 1 vấn đề duy nhất là pw default của user root quá lằng nhằng (nó bảo mật tất nhiên rồi), và ở môi trường dev bạn thực sự không cần thiết hoặc bạn muốn đổi pw thành tên crush chẳng hạn.

Thao tác đổi pw cho user root như sau

mysql> SET PASSWORD = PASSWORD('1234');
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

mysql> quit

Connect PHP and MySQL

You need to ensure PHP and MySQL can communicate with one another. There are several options to do so. I do the following:

Bước tiếp theo các bạn cần cấu hình để PHP và MySQL có thể làm việc được với nhau. Gõ lần lượt các lệnh sau

cd /var
mkdir mysql
cd mysql
ln -s /tmp/mysql.sock mysql.sock

Như vậy, bạn đã hoàn tất việc cài đặt Apache, PHP và MySQL trên Mac OS X. Tuy nhiên, nếu dừng ở đây, bạn có thể chưa có trình soạn thảo để viết mã PHP (bạn có thể dùng vi, nhưng sẽ tiện lợi hơn nếu có một ứng dụng giao diện đồ họa), và sẽ phải quản trị MySQL bằng dòng lệnh.

Để viết mã PHP, bạn có thể dùng các ứng dụng như Dreamwaver,… Riêng mình thì chọn dùng SublimeText vì nó nhỏ gọn và miễn phí.

Để quản trị MySQL, bạn có thể tải và cài đặt phpMyAdmin. Ứng dụng này dễ cài và dễ sử dụng. Mình đề xuất thêm ứng dụng Sequel Pro vì nó là ứng dụng desktop có giao diện đồ họa, sẽ giúp bạn thao tác nhanh chóng hơn. Ngoài ra, bạn cũng có thể xem xét dùng MySQL Workbench – một công cụ khá mạnh giúp quản trị và thao tác với MySQL.

NGUỒN THAM KHẢO INTERNET

Xem thêm: https://jason.pureconcepts.net/2015/10/install-apache-php-mysql-mac-os-x-el-capitan/

 

Cập nhật cho Mac OS Sierra, Version 10.12

I update to macOSS Sierra, Version 10.12

I face the same issue, I did two things to fix it properly. Following is my approaches.

1) Please check “/private/etc/apache2/extra/httpd-userdir.conf” file. Change

#Include /private/etc/apache2/users/*.conf

to

Include /private/etc/apache2/users/*.conf

2)**And edit your “/etc/apache2/httpd.conf”

change

Options FollowSymLinks Multiviews

to

Options FollowSymLinks Multiviews Indexes

finally your doc root will be look like the following,

DocumentRoot "/Library/WebServer/Documents"
<Directory "/Library/WebServer/Documents">
Options FollowSymLinks Multiviews Indexes
MultiviewsMatch Any
AllowOverride All
Require all granted

3) Restart apache

sudo apachectl restart

Still you facing the problem, Kindly check How to Set up Apache in macOS Sierra 10.12

March 18, 2017by thaotrinh
Học nghề

Laravel Request Lifecycle

Introduction

Khi bạn sử dụng tools trong “thế giới thực”, bạn sẽ cảm thấy tự tin hơn nếu bạn hiểu cách mà tool đó hoạt động. Trong các ứng dụng phần mềm cũng vậy, khi bạn hiểu về chắc chức năng phần mềm của mình, bạn sẽ cảm thấy thoải mái và tự tin khi sử dụng chúng.

Mục tiêu của tài liệu này là giúp bạn có được kiến thức (high-level) tổng quan tốt về cách mà Laravel framework làm việc. Bằng cách tìm hiểu tổng quan về framework, mọi thứ có vẻ sẽ bớt “ảo diệu” hơn và bạn sẽ trở nên tự tin khi xây dựng ứng dụng của mình. Nếu bạn không hiểu tất cả các điểu khoản ngay lập tức, đừng vội đầu hàng (don’t lose heart!). Hãy thử tìm hiểu từng khái niêm cơ bản trước và xem cách chúng hoạt động, và kiến thức của bạn sẽ tăng dần lên khi bạn khám phá các phần khác của tài liệu.

Lifecycle Overview

First Things
Bắt đầu của tất cả các requests tới ứng dụng Laravel là file public/index.php, tất cả các requests được điều hướng tới file này bằng cấu hình web server (Apache / Nginx). File index.php không chứa quá nhiều code. Thay vào đó nó là điểm bắt đầu để tải các phần của framework.

File index.php tải the Composer generated autoloader definition, và sau đó trả về một instance của ứng dụng Laravel từ đoạn mã trong bootstrap/app.php. Action đầu tiên tạo bởi Laravel là tạo ra một instance của ứng dụng / service container.

HTTP / Console Kernels
Tiếp theo, request sẽ được gửi tới HTTP kernel hoặc Console kernel, tùy thuộc vào loại request mà ứng dụng nhận được. 2 kernel này là trung tâm mà tất cả các request sẽ flow theo. Bây giờ, chúng ta sẽ tập trung vào HTTP kernel, được đặt trong app/Http/Kernel.

HTTP kernel kế thừa từ lớp Illuminate\Foundation\Http\Kernel, lớp này định nghĩa mảng bootstrappers sẽ chạy trước khi request được thực thi. Mảng bootstrappers này sẽ quản lý cấu hình lỗi, cấu hình logging, nhận diện môi trường của ứng dụng và thực thi các nhiệm vụ cần thiết phải hoàn thành trước khi request thực sự được thực thi.

HTTP kernel cũng định nghĩa một danh sách HTTP middleware mà tất cả các request sẽ phải chạy qua trước khi được quản lý bởi ứng dụng. Middleware này quản lý việc đọc và ghi HTTP session, xác định xem ứng dụng đang ở trạng thái bảo trì, xác thực CSRF token và rất nhiều tính năng khác.

Việc điều khiển của HTTP kernel rất đơn giản: nhận một Request và trả về một Response. Bạn có thể hiểu Kernel giống như một hộp đen lớn sẽ đại diện cho toàn bộ ứng dụng của bạn, nhận các HTTP Request và trả về các HTTP Response.

Service Providers

Một trong những actions quan trọng nhất của Kernel bootstrapping là loading service providers cho ứng dụng của bạn. Tất cả service providers cho ứng dụng được cấu hình trong file config/app.php. Đầu tiên, phương thức register sẽ được gọi trong tất cả các providers, sau đó, tất cả các providers sẽ được đăng ký (registered), lúc này phương thức boot sẽ được gọi.

Service providers sẽ chịu trách nhiệm khởi động tất cả các components khác nhau của framework, ví dụ như là database, queue, validation và routing. Kể từ khi chúng thực hiện khởi động và cấu hình tất cả tính năng được cung cấp bởi framework, service providers là phần quan trọng nhất của tiến trình thực thi Laravel.

Dispatch Request

Khi ứng dụng được khởi động và tất cả các service providers được đăng ký (registered), Request sẽ được chuyển đến bộ định tuyến (router) để gửi đi. Router sẽ gửi request tới một route hoặc một controller, cũng giống như chạy bất kì route đặc biệt nào trong middleware.

Focus On Service Providers

Service providers thật sự rất quan trọng trong việc khởi chạy ứng dụng Laravel. Khi một instance của ứng dụng được tạo, service providers sẽ được registered, và request sẽ được đưa đến (handed) ứng dụng bootstrapped. Nó thực sự rất đơn giản!

Nắm vững về cách một ứng dụng Laravel được xây dựng và khởi chạy thông qua service providers là rất quan trọng. Service providers mặc định trong ứng dụng của bạn được lưu trữ ở thư mục app/Providers

Mặc định, AppServiceProvider là rỗng. Provider này là nơi tốt nhất để thêm các đoạn mã khởi chạy cho ứng dụng của bạn và service container bindings. Tuy nhiên, với các ứng dụng lớn, bạn có thể tạo một vài service providers cho các mục đích khởi chạy khác nhau.

Tóm tắt

1. Tất cả các request gọi tới ứng dụng laravel đều chạy qua file public/index.php. File này load các phần của framework và tạo một instance của ứng dụng laravel.

2. Request sẽ chạy qua HTTP kernel hoặc Console kernel, HTTP kernel định nghĩa mảng Bootstrapper và HTTP middleware quản lý các cấu hình trước khi request được xử lý bởi ứng dụng.

3. Service providers sẽ chịu trách nhiệm khởi động tất cả các components khác nhau của framework.

4. Khi service providers được registered, request sẽ được gửi tới các route.

February 25, 2017by thaotrinh
Page 1 of 51234»...Last »

About me

Đề xuất cho bạn

Định nghĩa công việc theo phương pháp S.M.A.R.T

Định nghĩa công việc theo phương pháp S.M.A.R.T

Revision database

Revision database

Tạo đối tượng trong C# từ url API hoặc Json String

Git hướng dẫn cơ bản cho người mới

Git hướng dẫn cơ bản cho người mới

Không phải làm bao nhiêu mà là tạo ra bao nhiêu

Không phải làm bao nhiêu mà là tạo ra bao nhiêu

Bài mới

  • Định nghĩa công việc theo phương pháp S.M.A.R.T
  • Họp xong việc và họp thêm việc
  • Giá trị của Scrum Master trong case study của Leflair
  • Sự khác biệt giữa làm việc chăm chỉ và làm việc chăm chỉ một cách thông minh.
  • Một tách trà

Mọi người quan tâm

No comments to show.

Chuyên mục

  • Agile (APM)
  • Chuyện nghề
  • Đọc
  • Học nghề
  • Làm thợ
  • Uncategorized

Tags

Agile Dev Kanban Marketing Nhóm Scrum Sách Sản phẩm Think Tôi tự học

Người học thức, tức là người thà biết ít mà thật biết những gì mình biết, còn những gì mình không biết, thì cũng biết rõ là mình không biết. “Không có sự dốt nát nhục nhã bằng tin tưởng rằng mình đã biết trong khi mình chưa biết”. Văn hóa là một vấn đề thuộc phẩm chứ không phải thuộc lượng

© 2015 copyright thaotrinhminh@gmail.com // All rights reserved // Privacy Policy