1. Keep learning forward

    To be updated ...
  2. #TIL : Random quote 23 Feb 2017

    A computer lets you make more mistakes faster than any other invention in human history, with the possible exceptions of handguns and tequila. - Mitch Ratcliffe

    Haha, it's totally true ! And it makes me remember this meme when I was little bit drunk !

    Tequila

  3. #TIL : String problems can cause logical bugs in application

    Example table

    mysql> describe `test`;
    +------------+-------------+------+-----+-------------------+----------------+
    | Field      | Type        | Null | Key | Default           | Extra          |
    +------------+-------------+------+-----+-------------------+----------------+
    | id         | smallint(6) | NO   | PRI | NULL              | auto_increment |
    | name       | varchar(50) | NO   |     | NULL              |                |
    | created_at | timestamp   | YES  | MUL | CURRENT_TIMESTAMP |                |
    +------------+-------------+------+-----+-------------------+----------------+
    3 rows in set (0.00 sec)
    

    Here is dump file of the table

    DROP TABLE IF EXISTS `test`;
    
    CREATE TABLE `test` (
      `id` smallint(6) NOT NULL AUTO_INCREMENT,
      `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
      `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`),
      KEY `created_at` (`created_at`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    
    LOCK TABLES `test` WRITE;
    /*!40000 ALTER TABLE `test` DISABLE KEYS */;
    
    INSERT INTO `test` (`id`, `name`, `created_at`)
    VALUES
    	(1,'abc','2017-02-16 17:28:59'),
    	(2,' ABC','2017-02-16 17:29:14'),
    	(3,'ABC     ','2017-02-16 17:29:21'),
    	(4,'aBc','2017-02-16 17:29:31');
    
    /*!40000 ALTER TABLE `test` ENABLE KEYS */;
    UNLOCK TABLES;

    Case Insensitive

    When creating database, table and column, we have to set the default string COLLATION for them. And if we use collation end withs _ci, it means we ignore the Case Sensitive (or Case Insensitive).

    Then "abc" == "ABC" or "abc" == "aBc" or "abc" = "Abc" or ... (X = Y <=> UPPER(X) == UPPER(Y))

    mysql> select ("abc" = "ABC") as `case1`, ("abc" = "aBc") as `case2`, ("abc" = "Abc") as `case3`, ("abc" = "abcd") as `wrong`;
    +-------+-------+-------+-------+
    | case1 | case2 | case3 | wrong |
    +-------+-------+-------+-------+
    |     1 |     1 |     1 |     0 |
    +-------+-------+-------+-------+
    1 row in set (0.00 sec)
    

    String Trimming

    Check this out !

    mysql> select `id`, CONCAT("'", `name`, "'") as `name_with_quote`, `created_at` from test;
    +----+-----------------+---------------------+
    | id | name_with_quote | created_at          |
    +----+-----------------+---------------------+
    |  1 | 'abc'           | 2017-02-16 17:28:59 |
    |  2 | ' ABC'          | 2017-02-16 17:29:14 |
    |  3 | 'ABC '          | 2017-02-16 17:29:21 |
    |  4 | 'aBc'           | 2017-02-16 17:29:31 |
    +----+-----------------+---------------------+
    4 rows in set (0.00 sec)
    
    mysql> select `id`, CONCAT("'", `name`, "'") as `name_with_quote`, `created_at` from test where `name` = 'abc';
    +----+-----------------+---------------------+
    | id | name_with_quote | created_at          |
    +----+-----------------+---------------------+
    |  1 | 'abc'           | 2017-02-16 17:28:59 |
    |  3 | 'ABC '          | 2017-02-16 17:29:21 |
    |  4 | 'aBc'           | 2017-02-16 17:29:31 |
    +----+-----------------+---------------------+
    3 rows in set (0.01 sec)
    
    mysql> select `id`, CONCAT("'", `name`, "'") as `name_with_quote`, `created_at` from test where `name` = ' abc';
    +----+-----------------+---------------------+
    | id | name_with_quote | created_at          |
    +----+-----------------+---------------------+
    |  2 | ' ABC'          | 2017-02-16 17:29:14 |
    +----+-----------------+---------------------+
    1 row in set (0.00 sec)
    

    BAAMMMMM !!!

    holy-shit-the-illuminati-is-real

    MySQL do right trimming the string value before comparing.

    So you must be becareful to trim value before storing to MySQL to make everything consistent.

    Storing Emoji in MySQL

    Because Emoji use utf-8 4 bytes, so we must use the utf8mb4 charset (utf8 multi-bytes 4).

    It's safe when migrating charset from utf8 to utf8mb4 😎 , but not the reverse way 😅

  4. #TIL : Stats your top-10 frequently commands

    Run this command, it will show top-10 frequently commands, explain shell

    $ history | awk '{print $2}' | sort | uniq -c | sort -nr | head

    Example result

    2064 git
    1284 ls
     826 cd
     700 ssh
     602 clear
     491 python
     473 exit
     341 vagrant
     242 export
     167 ping
    
  5. #TIL : Bash shell shortcuts

    • Ctrl + e : jump cursor to EOL
    • Ctrl + a : jump cursor to BOL (beginning of line)
    • Ctrl + u : delete all from cursor to BOL
    • Ctrl + k : delete all from cursor to EOL
    • Ctrl + r : search history, press again for next search
    • Ctrl + l : clear shell screen
    • Ctrl + c : terminate the command (sometimes have to press twice)
    • Ctrl + z : suspend the command, back to shell. Run fg to resume the command
  6. #TIL : F-cking stupid limit of input vars

    Today, I tried to debug many hours to find out why my POST request missing some data (specify _token hidden field). :disappointed:

    I tried to config NGINX and PHPFPM max_post_size, client_max_body_size but they still gone. After 2-3 hours searching on Google, I found the link from PHP.net,
    it has a config value about limiting max input vars (default = 1000), so it causes the problem about missing data.

    So I changed max_input_vars = 9999 in my php.ini and everything works like a charm. :smiley:

    At least, I had a luck cos it doesn't run my POST request when missing the CSRF token :grin: My data is save !!!

  7. #TIL : Commands

    Command lsof

    List all opened files, sockets, pipes

    Eg:

    • List processes are using port 80 (need root if port between 1-1023)
    # sudo lsof -i:80
    • List processes are using /bin/bash
    # lsof /bin/bash
  8. #TIL : View real-time logs using websocketd

    I found a handy tool for making a websocket right on your shell.
    It is websocketd : http://websocketd.com/

    Its phisolophy is so simple :

    Just read incoming text from stdin and write outgoing text to stdout. Messaging is simple.

    Read its docs, I follow the ez tutorial 10 second tutorial and see how cool does it work.
    Let make something cool with this, we got a UNIX tool that print out to stdout in real-time with changes of end file.

    Ok cool, change the command to

    websocketd --port=8080 tail -f logs/web_access.log

    Tada ! Open the webpage that listens the websocket you made and see the magic :D You can tracking access log of website or system in real-time way.

  9. #TIL : Run built-in server via Docker

    Docker is the fast and clean way to run Linux programs.

    We can run a PHP project via PHP built-in server and Docker.

    docker run -it -p 8080:8080 -v `pwd`:/code php:7 php -S 0.0.0.0:8080 -t /code/web /code/web/server.php

    With server.php content is

    <?php
    
    $filename = __DIR__.preg_replace('#(\?.*)$#', '', $_SERVER['REQUEST_URI']);
    if (php_sapi_name() === 'cli-server' && is_file($filename)) {
        return false;
    
    }
    
    // Run application below
    $app = new Application();
    $app->run();
    
  10. #TIL : Reference assign object variable

    When you have a object x and assign y = x, y will be a ref of x (it looks like pointer of C). So changing property of y means changing property of x.

    Ex :

    x = {"a": 1, "b": 2}
    y = x
    y['a'] = 100
    print x['a'] # Result is 100

    So if you want clone the value, use copy lib :

    import copy
    x = {"a": 1, "b": 2}
    y = copy.deepcopy(x)
    y['a'] = 100
    print x['a'] # Result is 1
  11. #TIL : FTP via curl tool

    Can upload an file via FTP by curl tool with handy script :

    curl -T file_need_to_upload ftp://hostname --user user:passwd
  12. #TIL : Eloquent Many-to-Many Relationship

    To create the n-to-m relationship in Eloquent, we create a table stand between 2 tables.
    Eg:

    We have the db schema :

    postpost_tagtag
    id (PK)id (PK)id (PK)
    titlepost_id (Index)name (Unique)
    contenttag_id (Index)

    In the model Post and Tag, we define a relation :

    • App\Model\Post.php
    public function tags() {
        return $this->belongsToMany('App\Model\Tag', 'post_tag', 'post_id', 'tag_id');
    }
    • App\Model\Tag.php
    public function posts() {
        return $this->belongsToMany('App\Model\Post', 'post_tag', 'tag_id', 'post_id');
    }

    After that, we can use the relation to fetch the related data, like

    $post = Post::firstOrFail(1);
    $tags = $post->tags; // return the Collections class contains tags

    or

    $tag = Tag::where('name', '=', 'php')->first();
    $posts_of_tag = $tag->posts; // return the Collections class contains posts

    When updating or creating post, we have to sync with tags by

    $tag_ids = [2, 3 ,4]; // Get tag ids from tag names
    $post->tags()->sync($tag_ids);
  13. #TIL : String Format Unicode params

    unicode_thing = u"Xin chào mọi người"
    a = '{}'.format(unicode_thing)

    will cause the error UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 6: ordinal not in range(128)

    The solution is add u prefix the pattern (it means using unicode pattern) :

    unicode_thing = u"Xin chào mọi người"
    a = u'{}'.format(unicode_thing)
  14. #TIL : Index is useless when use function on indexed field

    Reality, if using function on indexed field, you will broke indexing by accident.
    Eg:

    WHERE MONTH(`date`) = 11 AND YEAR(`date`) = 2015

    Solution is transform the query to comparison query, like this :

    WHERE `date` >= '2015-11-01' AND `date` < '2015-12-01'
  15. #TIL : Shortcut keyboard improve productivity

    • Open the preference of any Application by Cmd + ,.
    • Press Cmd + ~ to go previous App when switching App on Cmd + Tab
    • Copy screenshot to clipboard by Cmd + Ctl + Shift + 3
    • Press Option when click to notification center is putting it on “Do no disturb” mode.
  16. #TIL : Debugging Chrome extension

    • To open directly the Console Dev Tools, press Cmd + Opt + J in MacOSX.
    • To debug easily the any files of extension, open the url chrome-extension://<extension-id>/<file-name> in address bar.