常常為了地址的事情感到麻煩,所以寫了一個程式能把舊5都地址轉新5都地址,再取得區碼的程式
[packagist.org](https://packagist.org/packages/recca0120/twzipcode)
[github](https://github.com/recca0120/twzipcode)
```bash
composer require recca0120/twzipcode
```
```php
use Recca0120\Twzipcode\Twzipcode;
$twzipcode = new Twzipcode('北 縣 萬里鄉中正路100號');
$twzipcode->getZipcode(); // 207
$twzipcode->getCounty(); // 新北市
$twzipcode->getDistrict(); // 萬里區
$twzipcode->getAddress(); // 新北市萬里區中正路100號
$twzipcode->getShortAddress(); // 中正路100號
```
PHPer
2016年6月6日 星期一
2016年6月5日 星期日
Laravel Repository
最近寫好的repository的package
還沒時間整理readme
所以就先拿phpunit來充當readme
[packagist.org](https://packagist.org/packages/recca0120/repository)
[github](https://github.com/recca0120/laravel-repository)
# Laravel Repository
[![Latest Stable Version](https://poser.pugx.org/recca0120/repository/v/stable)](https://packagist.org/packages/recca0120/repository)
[![Total Downloads](https://poser.pugx.org/recca0120/repository/downloads)](https://packagist.org/packages/recca0120/repository)
[![Latest Unstable Version](https://poser.pugx.org/recca0120/repository/v/unstable)](https://packagist.org/packages/recca0120/repository)
[![License](https://poser.pugx.org/recca0120/repository/license)](https://packagist.org/packages/recca0120/repository)
[![Monthly Downloads](https://poser.pugx.org/recca0120/repository/d/monthly)](https://packagist.org/packages/recca0120/repository)
[![Daily Downloads](https://poser.pugx.org/recca0120/repository/d/daily)](https://packagist.org/packages/recca0120/repository)
### Demo in tests/RepositoryTest.php
```php
use Faker\Factory as FakerFactory;
use Illuminate\Database\Eloquent\Model;
use Mockery as m;
use Recca0120\Repository\Criteria;
use Recca0120\Repository\EloquentRepository;
class EloquentRepositoryTest extends PHPUnit_Framework_TestCase
{
use Laravel;
public function setUp()
{
$app = $this->createApplication();
$db = $this->createDatabase();
Schema::create('users', function ($table) {
$table->increments('id');
$table->string('name');
$table->string('email');
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
});
Schema::create('roles', function ($table) {
$table->increments('id');
$table->string('name');
$table->string('description');
$table->timestamps();
});
Schema::create('user_roles', function ($table) {
$table->integer('user_id');
$table->integer('role_id');
});
$faker = FakerFactory::create();
for ($i = 0; $i < 3; $i++) {
User::create([
'name' => sprintf('%03d', $i + 1),
'email' => sprintf('%03d@test.com', $i + 1),
'password' => $faker->text,
]);
}
Role::create([
'name' => 'superuser',
'description' => 'superuser',
]);
Role::create([
'name' => 'administrator',
'description' => 'administrator',
]);
User::find(1)->roles()->sync([1]);
}
public function tearDown()
{
m::close();
Schema::drop('users');
}
public function test_repository_create()
{
$repository = new EloquentRepository(new User());
$repositoryUser = $repository->create([
'name' => 'test9999',
'email' => 'test9999@test.com',
'password' => str_random(30),
]);
$modelUser = User::where('name', '=', 'test9999')->first();
$this->assertSame($repositoryUser->id, $modelUser->id);
}
public function test_repository_find()
{
$repository = new EloquentRepository(new User());
$repositoryUser = $repository->find(1);
$modelUser = User::find(1);
$this->assertSame($repositoryUser->id, $modelUser->id);
}
public function test_repository_update()
{
$repository = new EloquentRepository(new User());
$repositoryUser = $repository->update([
'password' => 'test_update',
], 2);
$modelUser = User::find(2);
$this->assertSame($repositoryUser->id, $modelUser->id);
$this->assertSame($modelUser->password, 'test_update');
}
public function test_repository_delete()
{
$counter = User::count();
$repository = new EloquentRepository(new User());
$this->assertTrue($repository->delete(1));
$this->assertSame(User::count(), $counter - 1);
}
public function test_repository_find_all()
{
$repository = new EloquentRepository(new User());
$repositoryUsers = $repository->findAll();
$modelUsers = User::all();
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
public function test_find_by_criteria()
{
$repository = new EloquentRepository(new User());
$criteria = (new Criteria())
->where('name', '0001')
->having('email', '=', '0001@test.com')
->groupBy('name');
$repositoryUsers = $repository->findBy($criteria);
$modelUsers = User::where('name', 'like', '0001')
->where('email', '0001@test.com')
->groupBy('name')
->get();
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
public function test_find_by_criteria_where()
{
$repository = new EloquentRepository(new User());
$criteria = (new Criteria())
->where('name', '0001');
$repositoryUsers = $repository->findBy($criteria);
$modelUsers = User::where('name', '0001')
->get();
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
public function test_find_by_criteria_where_closure()
{
$repository = new EloquentRepository(new User());
$criteria = (new Criteria())
->where(function ($criteria) {
return $criteria->where('name', '0001');
});
$repositoryUsers = $repository->findBy($criteria);
$modelUsers = User::where(function ($query) {
return $query->where('name', '0001');
})->get();
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
public function test_find_by_criteria_or_where()
{
$repository = new EloquentRepository(new User());
$criteria = (new Criteria())
->where('name', '0001')
->orWhere('name', '0002');
$repositoryUsers = $repository->findBy($criteria);
$modelUsers = User::where('name', '0001')
->orWhere('name', '0002')
->get();
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
public function test_find_by_criteria_or_where_closure()
{
$repository = new EloquentRepository(new User());
$criteria = (new Criteria())
->where(function ($criteria) {
return $criteria->where('name', '0001')
->orWhere('name', '0002');
});
$repositoryUsers = $repository->findBy($criteria);
$modelUsers = User::where(function ($query) {
return $query->where('name', '0001')
->orWhere('name', '0002');
})->get();
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
public function test_criteria_where_has()
{
$repository = new EloquentRepository(new User());
$criteria = (new Criteria())
->whereHas('roles', function ($criteria) {
return $criteria->where('id', '=', 1);
});
$repositoryUsers = $repository->findBy($criteria);
$modelUsers = User::whereHas('roles', function ($query) {
return $query->where('id', '=', 1);
})
->get();
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
public function test_criteria_join()
{
$repository = new EloquentRepository(new User());
$criteria = (new Criteria())
->join('user_roles', function ($criteria) {
return $criteria->on('users.id', '=', 'user_roles.user_id');
});
$repositoryUsers = $repository->findBy($criteria);
$modelUsers = User::join('user_roles', function ($query) {
return $query->on('users.id', '=', 'user_roles.user_id');
})
->get();
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
public function test_criteria_order_by()
{
$repository = new EloquentRepository(new User());
$criteria = (new Criteria())
->orderBy('name', 'desc');
$repositoryUsers = $repository->findBy($criteria);
$modelUsers = User::orderBy('name', 'desc')
->get();
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
public function test_criteria_select()
{
$repository = new EloquentRepository(new User());
$criteria = (new Criteria())
->select('name');
$repositoryUsers = $repository->findBy($criteria);
$modelUsers = User::select('name')
->get();
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
public function test_criteria_experssion()
{
$repository = new EloquentRepository(new User());
$criteria = (new Criteria())
->select(Criteria::expr('REPLACE(name, "0001", "0003")'));
$repositoryUsers = $repository->findBy($criteria);
$modelUsers = User::select(DB::raw('REPLACE(name, "0001", "0003")'))
->get();
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
public function test_criteria_paginated()
{
$repository = new EloquentRepository(new User());
$repositoryUsers = $repository->paginatedAll(15);
$modelUsers = User::paginate(15);
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
public function test_criteria_with()
{
$repository = new EloquentRepository(new User());
$criteria = (new Criteria())
->with('roles');
$repositoryUsers = $repository->findBy($criteria);
$modelUsers = User::with('roles')->get();
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
public function test_find_by_array()
{
$repository = new EloquentRepository(new User());
$repositoryUsers = $repository->findBy([
['name', '=', '0002'],
['email', '=', '0002@test.com'],
]);
$modelUsers = User::where('name', '0002')
->where('email', '0002@test.com')->get();
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
public function test_find_by_array_key()
{
$repository = new EloquentRepository(new User());
$repositoryUsers = $repository->findBy([
'name' => '0002',
'email' => '0002@test.com',
]);
$modelUsers = User::where('name', '0002')
->where('email', '0002@test.com')->get();
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
public function test_custom_criteria()
{
$repository = new EloquentRepository(new User());
$repositoryUsers = $repository->findBy(new CustomCriteria());
$modelUsers = User::where('name', '0002')->get();
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
public function test_multiple_criteria()
{
$repository = new EloquentRepository(new User());
$repositoryUsers = $repository->findBy([
new CustomCriteria(),
(new Criteria())->orderBy('name', 'desc'),
]);
$modelUsers = User::where('name', '0002')
->orderBy('name', 'desc')->get();
$this->assertSame($repositoryUsers->toArray(), $modelUsers->toArray());
}
}
class CustomCriteria extends Criteria
{
public function __construct()
{
$this->where('name', '0002');
}
}
class User extends Model
{
protected $fillable = [
'name', 'email', 'password',
];
public function roles()
{
return $this->belongsToMany(
Role::class,
'user_roles',
'role_id',
'user_id'
);
}
}
class Role extends Model
{
protected $fillable = [
'name', 'description',
];
public function users()
{
return $this->belongsToMany(
self::class,
'user_roles',
'user_id',
'role_id'
);
}
}
function dump()
{
call_user_func_array('var_dump', func_get_args());
}
```
Laravel Terminal
這是一個將artisan移植到web介面的package,
並增加了一些自定義的command
在server不支援bash shell時,還能執行一些aritsan的命令
[packagist.org](https://packagist.org/packages/recca0120/terminal)
[github](https://github.com/recca0120/laravel-terminal)
# Laravel Web Artisan
[![Latest Stable Version](https://poser.pugx.org/recca0120/terminal/v/stable)](https://packagist.org/packages/recca0120/terminal)
[![Total Downloads](https://poser.pugx.org/recca0120/terminal/downloads)](https://packagist.org/packages/recca0120/terminal)
[![Latest Unstable Version](https://poser.pugx.org/recca0120/terminal/v/unstable)](https://packagist.org/packages/recca0120/terminal)
[![License](https://poser.pugx.org/recca0120/terminal/license)](https://packagist.org/packages/recca0120/terminal)
[![Monthly Downloads](https://poser.pugx.org/recca0120/terminal/d/monthly)](https://packagist.org/packages/recca0120/terminal)
[![Daily Downloads](https://poser.pugx.org/recca0120/terminal/d/daily)](https://packagist.org/packages/recca0120/terminal)
## Installation
Add Presenter to your composer.json file:
```js
"require": {
"recca0120/terminal": "^1.3.3"
}
```
Now, run a composer update on the command line from the root of your project:
```
composer update
```
### Registering the Package
Include the service provider within `app/config/app.php`. The service povider is needed for the generator artisan command.
```php
'providers' => [
...
Recca0120\Terminal\ServiceProvider::class,
...
];
```
publish
```php
artisan vendor:publish --provider="Recca0120\Terminal\ServiceProvider"
```
### URL
http://localhost/path/to/terminal
### Whitelist
```php
return [
'whitelists' => ['127.0.0.1', 'your ip'],
];
```
## Available Commands
* artisan
* artisan tinker
* find
* mysql
### Find
not full support, but you can delete file use this function (please check file permission)
```bash
find ./vendor -name tests -type d -maxdepth 4 -delete
```
## Add Your Command
### Add Command Class
```php
// src/Console/Commands/Mysql.php
namespace Recca0120\Terminal\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Foundation\Inspiring;
class Inspire extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'inspire';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Display an inspiring quote';
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->comment(PHP_EOL.Inspiring::quote().PHP_EOL);
}
}
```
### Add Command
```php
// src/Console/Kernel.php
namespace Recca0120\Terminal\Console;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Recca0120\Terminal\Console\Application as Artisan;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
Commands\Inspire::class,
];
}
```
## ScreenShot
### Available Commands
```bash
$ help
```
![Available Commands](https://cdn.rawgit.com/recca0120/terminal/master/screenshots/available-commands.png)
### Artisan List
```bash
$ artisan
```
![Artisan List](https://cdn.rawgit.com/recca0120/terminal/master/screenshots/artisan-list.png)
### Migrate
```bash
$ artisan migrate --seed
```
![Migrate](https://cdn.rawgit.com/recca0120/terminal/master/screenshots/artisan-migrate.png)
### Artisan Tinker
```bash
$ artisan tinker
```
![Tinker](https://cdn.rawgit.com/recca0120/terminal/master/screenshots/artisan-tinker.png)
### Find Command
```bash
$ find ./ -name * -maxdepth 1
```
![Find Command](https://cdn.rawgit.com/recca0120/terminal/master/screenshots/find-command.png)
### Find and Delete
```bash
$ find ./storage/logs -name * -maxdepth 1 -delete
```
![Find and Delete](https://cdn.rawgit.com/recca0120/terminal/master/screenshots/find-and-delete.png)
### Vi
```bash
$ vi server.php
```
![Vi Command](https://cdn.rawgit.com/recca0120/terminal/master/screenshots/vi-command.png)
![Vi Editor](https://cdn.rawgit.com/recca0120/terminal/master/screenshots/vi-editor.png)
![Vi Save](https://cdn.rawgit.com/recca0120/terminal/master/screenshots/vi-save.png)
### Tail
```bash
$ tail
$ tail --line=1
$ tail server.php
$ tail server.php --line 5
```
![Tail Command](https://cdn.rawgit.com/recca0120/terminal/master/screenshots/tail-command.png)
### Cleanup
```bash
$ cleanup
```
![Cleanup Command](https://cdn.rawgit.com/recca0120/terminal/master/screenshots/cleanup-command.png)
Laravel Tracy
一個laravel的debug工具,它是MIT的!大家可以安裝來試看看
用得習慣的話就請多多使用....
[packagist.org](https://packagist.org/packages/recca0120/laravel-tracy)
[github](https://github.com/recca0120/laravel-tracy)
## [Nette Tracy](https://github.com/nette/tracy.git) for Laravel 5
Better Laravel Exception Handler
[![Latest Stable Version](https://poser.pugx.org/recca0120/laravel-tracy/v/stable)](https://packagist.org/packages/recca0120/laravel-tracy)
[![Total Downloads](https://poser.pugx.org/recca0120/laravel-tracy/downloads)](https://packagist.org/packages/recca0120/laravel-tracy)
[![Latest Unstable Version](https://poser.pugx.org/recca0120/laravel-tracy/v/unstable)](https://packagist.org/packages/recca0120/laravel-tracy)
[![License](https://poser.pugx.org/recca0120/laravel-tracy/license)](https://packagist.org/packages/recca0120/laravel-tracy)
[![Monthly Downloads](https://poser.pugx.org/recca0120/laravel-tracy/d/monthly)](https://packagist.org/packages/recca0120/laravel-tracy)
[![Daily Downloads](https://poser.pugx.org/recca0120/laravel-tracy/d/daily)](https://packagist.org/packages/recca0120/laravel-tracy)
## Features
- Visualization of errors and exceptions
- Debugger Bar
- Exception stack trace contains values of all method arguments.
## Online Demo
[Demo](https://cdn.rawgit.com/recca0120/laravel-tracy/master/screenshots/tracy-exception.html)
## Installing
To get the latest version of Laravel Exceptions, simply require the project using [Composer](https://getcomposer.org):
```bash
composer require recca0120/laravel-tracy
```
Instead, you may of course manually update your require block and run `composer update` if you so choose:
```json
{
"require": {
"recca0120/laravel-tracy": "~1.3.5"
}
}
```
Include the service provider within `config/app.php`. The service povider is needed for the generator artisan command.
```php
'providers' => [
...
Recca0120\LaravelTracy\ServiceProvider::class,
...
];
```
publish
```bash
artisan vendor:publish --provider="Recca0120\LaravelTracy\ServiceProvider"
```
## Config
```php
return [
'ajax' => [
'debugbar' => false, // enable render debugbar when http request is ajax
'gzCompressLevel' => 5, // gzcompress level
/*
* http://stackoverflow.com/questions/3326210/can-http-headers-be-too-big-for-browsers/3431476#3431476
* Lowest limit found in popular browsers:
* - 10KB per header
* - 256 KB for all headers in one response.
* - Test results from MacBook running Mac OS X 10.6.4:
*/
'maxHeaderSize' => 102400, // 102400b its => 100 kb
],
'basePath' => null,
'strictMode' => true,
'maxDepth' => 4,
'maxLen' => 1000,
'showLocation' => true,
'editor' => 'subl://open?url=file://%file&line=%line',
'panels' => [
'routing' => true,
'database' => true,
'view' => true,
'session' => true,
'request' => true,
'event' => false,
'user' => true,
'terminal' => true,
],
// value: js or tracy
'panelDumpMethod' => 'js', // tracy dump need more memory
];
```
### Editor Link
windows
```
copy /recca0120/laravel-tracy/tools/subl-handler/subl-handler.vbs to any directory where you want to place
double click subl-handler.vbs and select editor (support eclipse, sublime, notepad++, else...)
```
OSX
```
https://github.com/dhoulb/subl
```
## Debugger Bar
### SystemInfo
![SystemInfo](https://cdn.rawgit.com/recca0120/laravel-tracy/master/screenshots/systeminfo.png)
### Route
![Route](https://cdn.rawgit.com/recca0120/laravel-tracy/master/screenshots/route.png)
### View
![View](https://cdn.rawgit.com/recca0120/laravel-tracy/master/screenshots/view.png)
### Session
![Session](https://cdn.rawgit.com/recca0120/laravel-tracy/master/screenshots/session.png)
### Request
![Request](https://cdn.rawgit.com/recca0120/laravel-tracy/master/screenshots/request.png)
### Login
![Login](https://cdn.rawgit.com/recca0120/laravel-tracy/master/screenshots/login.png)
### Web Artisan
web artisan is another package [recca0120/terminal](https://github.com/recca0120/laravel-terminal)
![Terminal](https://cdn.rawgit.com/recca0120/laravel-tracy/master/screenshots/terminal.png)
#### notice
if you install terminal before, this panel will throw errors, please remove folder `app/resources/views/vendor/terminal`
## ISSUE
when ajax debugbar is enabled and debugbar is bigger than 256k, will throw 500 exception, or browser will be no response
so I try to compress debugbar in php, and decompress debugbar in javascript.
It looks like working at chrome 48.0.2564.116 64bit, windows 10
but if you use Laravel-Tracy and it doesn't work correctly
you can try
- disable panel [view , request, event]
- panelDumpMethod change to js
- disable ajax debugbar
2016年5月12日 星期四
活用 es6 generator + co 讓async看起來像sync
仔細研究了es6的generator function + [co](https://github.com/tj/co "co")
才發現可以利用它來改善我們的程式寫法
讓程式的可讀性更高
先讓我們看看用Promise來撰寫非同步code的樣子
```javascript
let num = function (num) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(num+1);
}, 500);
});
}
num(1).then((res) => {
return num(res);
}).then((res) => {
return num(res);
}).then((res) => {
// output
// promise result: 4
console.log(`promise result: ${res}`);
});
```
接下來讓我們來看看generator function + [co](https://github.com/tj/co "co")的寫法
```javascript
let num = function (num) {
return (callback) => {
setTimeout(function() {
callback(null, num+1);
}, 500);
}
}
co(function*() {
let num1 = yield num(1);
let num2 = yield num(num1);
let num3 = yield num(num2);
return num3;
}).then((res) => {
// output
// generator result: 4
console.log(`generator result: ${res}`);
});
```
[jsfiddle](https://jsfiddle.net/recca0120/eocp5h2c/ "jsfiddle範例")
2016年4月25日 星期一
ubuntu下安裝atom editor
只要執行三行指令即可
```bash
sudo add-apt-repository ppa:webupd8team/atom
sudo apt-get update
sudo apt-get install atom
```
Linux使用php7連接mssql,並設定utf-8
使用php7要連接mssql要安裝的套件為pdo_dblib
```bash
# centos
yum install php70w-pdo_dblib.x86_64
# ubuntu
sudo apt-get install freetds-bin php-sybase
```
接下來我們更改freetds的設定檔,裝連線設定為utf8
```bash
# centos
vi /etc/freetds.conf
# ubuntu
sudo vi /etc/freetds/freetds.conf
```
加入兩行設定即可
```ini
# centos
tds version = 7.2
client charset = UTF-8
# ubuntu
tds version = 7.1
client charset = UTF-8
```
![freetds config](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfZxvhvTwGAuP2pwtB80Bbypwb54mp8uAIPe5kAPEB8Swk4l5BFpt0ZncIr_SMZ43RW5ibnF7SOP_AeE5D7PX5JFbk2uBPZkK_Q0jL0MFFlMXRkmgJeUNFv17CszpfALpdfu-HJ23aKN92/s1600/Image+3.png)
設定完成後連線到mssql charset就會是utf8
如果還是顯示為亂碼的話則可以利用tsql的指令來debug
```bash
tsql -S [ip] -U [username] -P [password]
```
![tsql](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhplyPJmyyXaqfmXpo1D9Tl72GhIOrn_P2QgjwASD3-QNn_3YUyVBsCX6FPv0TdYC6D9hhYd2JIVR8OEHZXnBErLy2004Kmsah5y1YOqCoZ5WtiPL5sbYzWiB-6dxaPz3OKny6Ji2qJw-Vf/s1600/Image+2.png)
訂閱:
文章 (Atom)