书写技术成长之路

MySQL 常用查询总结

查看当前连接状态信息

STATUS;

查看可用的存储引擎

SHOW ENGINES;

查看是否自动提交事务

SELECT @@autocommit;

查看当前连接和事务的隔离级别

select @@tx_isolation;
select @@global.tx_isolation;

查看当前数据库

SELECT database();

从当前表结构创建出新表

CREATE TABLE new_tbl LIKE orig_tbl;

查询一个表中含有重复的记录数

SELECT id, count(*) FROM users  group by name having count(*) > 1;

删除重复的记录并保留一个最小的ID

DELETE a FROM user a, user b WHERE a.id > b.id AND a.mail = b.mail;

删除重复的记录并保留一个最大的ID

DELETE a FROM user a, user b WHERE a.id < b.id AND a.mail = b.mail;

查看表信息

SHOW TABLE STATUS LIKE TABLE_NAME

查看索引信息

SHOW INDEX FROM TABLE_NAME

查看执行计划

EXPLAIN SELECT * FROM TABLE_NAME

添加索引

1. CREATE INDEX email_idx ON `TABLE_NAME`;
2. ALTER TABLE TABLE_NAME ADD INDEX email_idx (email);

删除索引

1. DROP INDEX email_idx ON `TABLE_NAME`;
2. ALTER TABLE `TABLE_NAME` DROP INDEX INDEX_NAME;

删除有外键约束的记录

InnoDB不允许删除一个被FOREIGN KEY表约束引用的表,除非设置了FOREIGN_KEY_CHECKS=0;
SET FOREIGN_KEY_CHEECKS = 0;

替换

UPDATE tbl_name 
SET 
    field_name = REPLACE(field_name,
        string_to_find,
        string_to_replace)
WHERE
    conditions;

C 指针和数组

#include <stdio.h>

int main()
{
    char board[3][3] = {
        {'1', '2', '3'},
        {'4', '5', '6'},
        {'7', '8', '9'},
    };

    printf("value of board[0][0]: %c\n", board[0][0]);
    printf("value of *board[0]: %c\n", *board[0]);
    printf("value of **board: %c\n", **board);          // 如果使用board获取第一个元素的值,就需要使用两个间接运算符**board

    // 只使用一个间接运算符,只会得到子数组的第一个元素,即board[0]引用的地址
    printf("address of board[0]: %p\n", *board);
}

PHP 常见误区

foreach 循环中的变量引用

foreach中的变量引用可以用来更改数组中的元素,例如

$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
    $value = $value * 2;
} 
// $arr foreach后的值为(2, 4, 6, 8)

但是变量的引用也会导致一些意想不到的bug,比如下面的例子

$array = [1, 2, 3];
foreach ($array as &$value) {} // 通过引用的方式, $value是数组$array元素的引用
echo implode(',', $array), "\n";

foreach ($array as $value) {} // 通过赋值的方式
echo implode(',', $array), "\n";

// 结果是
1,2,3
1,2,2

后面再循环$array的结果却不是1,2,3而是1,2,2 这是因为在每一次循环过后,$array中的元素都会赋给$value, 因为$value是引用的方式,在循环结束后,$value仍然引用数组的最后一个元素,也就是$array[2], 这时候在第二次foreach循环的时候,因为$value仍然是引用$array[2], 当把数组中的每一个元素赋给$value的时候,$array[2]的值也跟着改变,在第二次foreach的时候

  1. 把$array[0]赋值给$value,因为$value是引用$array[2], 所以这个时候$array[2]的值也变为1
  2. 把$array[1]赋值给$value的时候,因为$value是引用$array[2], 所以$array[2]的值变为2
  3. 这个时候需要把$array[2]的值赋给$value, 因为$array[2]=2,所以$value的值也是2 这样,foreach之后,$array的元素就变为[1, 2, 2]了。 所以在foreach修改元素值的时候,为了避免引入bug,就需要删除引用
$arr = array(1, 2, 3);
foreach ($arr as &$value) {
    $value = $value * 2;
}
unset($value);       // 删除$value和$arr中最后一个元素的引用

isset的误区

isset检查变量是否设置的时候并不可靠

$arr = [];
$arr['name'] = null;

var_dump(isset($arr['name'])); // result is false

// 如果要检测变量是否存在并不为空
if ($arr['name']) {
   // key存在并不为空
} else {

}

isset在变量的值是null的时候依然会返回false, 所以如果要检测变量存在并且不为空要使用if来判断,最主要的是取决于你期望获得的结果是什么。

$_POST误区

$_POST超级全局变量并不总是能获得POST方法提交来的数据

$.ajax({
    url: 'http://my.site/some/path',
    method: 'post',
    data: JSON.stringify({a: 'a', b: 'b'}),
    contentType: 'application/json'
});

上面这段通过ajax请求并且请求方法是post,不过它的contentType是application/json,这种方式在当前开发中很常见, 但是打印$_POST输出的却是空数组,这是为什么呢? 这是因为在POST方法请求PHP执行时,PHP只能处理content type是application/x-www-form-urlencode或者multipart/form-data格式的, 所以上面这种application/json Content Type不在$_POST变量中,那么我们该怎么处理这种格式呢

// 通过这种方式来获得content type是`application/json`的数据
$data = json_decode(file_get_contents('php://input'), true);

参考

https://www.toptal.com/php/10-most-common-mistakes-php-programmers-make

PHP MongoDB 基本使用

PHP56需要安装php56-mongo, 而不是php56-mongodb

安装 brew install php56-mongo

然后重启PHP-FPM brew services restart php56

连接MongoDB和基本使用

<?php

$mongodb = new MongoClient;

// select a database
$db = $mongodb->test;

// select a collection
$collection = $db->test;

// add a record
$document = array('title' => 'Calvin and Hobbes', 'author' => 'Bill Watterson');
$collection->insert($document);

// add another record, with a different "shape"
$document = array('title' => 'XKCD', 'online' => true);
$collection->insert($document);

// find title not null in the collection
$cursor = $collection->find(['title' => ['$ne' => null]]);

// iterate through the results
foreach ($cursor as $obj) {
    echo $obj['title']."\n";
}

MongoDB 插入

<?php

/**
 * MongoDB Insert Operation
 */
$mongoDB = new MongoClient;

// select collection
$collection = $mongoDB->example->users;

$insertOneResult = $collection->insert([
    'username' => 'admin',
    'email' => 'admin@example.com',
    'name' => 'Admin User',
    'creat_time' => time(),
]);

var_dump($insertOneResult);

MongoDB 查询

<?php

/**
 * MongoDB Query 
 */

$mongoDB = new MongoClient();

$collection = $mongoDB->example->users;

$document = $collection->findOne(['username' => 'admin']);

var_dump($document);

$cursor = $collection->find(['username' => 'admin'], ['username' => true, 'email' => true, 'create_time' => true])->sort(['create_time' => -1])->limit(2);

foreach ($cursor as $document) {
    var_dump($document);
}

参考

php.net #The MongoCollection class#

PHP 多维数组排序

<?php

/**
 * 方案一
 * @param  array  $arr   待排序数组
 * @param  string $key   指定排序的key
 * @param  string $order 降序或升序
 * @return array         排序后的数组
 */
function multi_sort1($arr, $key, $order = 'ASC')
{
    $temp = [];
    foreach ($arr as $val) {
        $temp[] = $val[$key];
    }

    if ($order == 'ASC') {
        return array_multisort($temp, SORT_ASC, $arr);
    } else {
        return array_multisort($temp, SORT_DESC, $arr);
    }
}

/**
 * 方案二
 * @param  array  $arr   待排序数组
 * @param  string $key   指定排序的key
 * @param  string $order 降序或升序
 * @return array         排序后的数组
 */
function multi_sort2($arr, $key, $order = 'ASC') {

    if ($order == 'ASC') {
        usort($arr, function($a, $b) {
            return $a[$key] > $b[$key] ? 1 : -1;
        });
    } else {
        usort($arr, function($a, $b) {
            return $a[$key] > $b[$key] ? -1 : 1;
        });
    } 
}

二分查找算法

<?php

/**
* binary search
*/
function binary_search($array, $find, $low, $high)
{
    if ($low <= $high) {
        $middle = intval(($low+$high)/2);
    }
    if ($array[$middle] == $find) {
        return $middle;
    } elseif ($array[$middle] < $find) {
        return binary_search($array, $find, $middle+1, $high);
    } else {
        return binary_search($array, $find, $low, $middle-1);
    }
}

$array = [2, 6, 10, 23, 46, 54, 62, 72, 83, 96];
$index = binary_search($array, 23, 0, count($array));
echo $index;

排序算法(四) 快速排序

<?php

/**
 * quick sort
 */
function quick_sort($array) {
    $len = count($array);

    if ($len <= 1) {
        return $array;
    }

    $base = $array[0];
    $left_arr = $right_arr = [];

    for ($i=1; $i<$len; $i++) {
        if ($array[$i] <= $base) {
            $left_arr[] = $array[$i];
        } else {
            $right_arr[] = $array[$i];
        }
    }

    $left_arr= quick_sort($left_arr);
    $right_arr = quick_sort($right_arr);
    return array_merge($left_arr, array($base), $right_arr);
}

$arr = [10, 2, 6, 14, 26, 88, 36, 47, 22, 80, 92];
$result = quick_sort($arr);
print_r($result);

排序算法(三) 插入排序

<?php

/**
 * insertion sort
 */
$arr = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48];
$len = count($arr);

for ($j=1; $j < $len; $j++) {   
    $key = $arr[$j];  
    $i = $j - 1;    // set the first element as sorted

    // when current element smaller than before element, set current element with before element
    while($i >= 0 and $arr[$i] > $key) {  
        $arr[$i + 1] = $arr[$i];  
        $i--;  
    }  

    // insert current element  
    $arr[$i + 1] = $key;  
}

print_r($arr);

排序算法(二) 选择排序

<?php

/**
 * select sort
 */
$arr = [3, 44, 38, 5, 47, 15, 36, 27, 2, 46, 4,19, 50];
$len = count($arr);

for ($i=0; $i<$len; $i++)
{
    // set the first as the minimum
    $min = $i;
    for ($j=$i+1; $j<$len; $j++) {
        if ($arr[$j]<$arr[$min]) {
            $min = $j;  // set element as the new minimum index
        }
    }

    // swap
    $temp = $arr[$i];
    $arr[$i] = $arr[$min];
    $arr[$min] = $temp;
}

print_r($arr);

排序算法(一) 冒泡排序

<?php

/**
 * bubble sort
 */
$a = [12, 1, 8, 9, 23, 36, 48, 52, 66, 72, 80, 91];
$len = count($a);

for ($i=0; $i<$len; $i++) {
    for ($j=0; $j<$len; $j++) {
        // swap 
        if ($a[$i] > $a[$j]) {
            $temp = $a[$j];
            $a[$j] = $a[$i];
            $a[$i] = $temp;
        }
    }
}

print_r($a);