markdown 50 Laravel技巧

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown 50 Laravel技巧相关的知识,希望对你有一定的参考价值。

# Reference

1. https://speakerdeck.com/willroth/50-laravel-tricks-in-50-minutes
2. https://www.reddit.com/r/laravel/comments/3to60i/50_laravel_tricks/

# ToC

###### A. Eloquent

* 1\. Automatic Model Validation
* 2\. Prevent Uploading
* 3\. Conditional Relationships
* 4\. Expressive "where" syntax
* 5\. Query Builder: having raw
* 6\. Simple Date filtering
* 7\. Save options
* 8\. Multilanguage Support *
* 9\. Retreive random rows
* 10\. UUID Model Primary Keys
* 11\. Ordered relationships
* 12\. Simple incrementing and Decrementing
* 13\. Lists with Mutations
* 14\. Appending mutated properties
* 15\. Filter only rows with Child rows
* 16\. Return relations on model save

###### B. Blade

* 17\. Dynamic With
* 18\. First/Last Array Element
 
###### C. Collections

* 19\. Arrays as Collections
* 20\. Collection Filters
* 21\. find()
* 22\. where()
* 23\. implode()
* 24\. where() & list()
* 25\. Order belongsToMany by pivot table value
* 26\. Sorting with closures
* 27\. Keying arrays
* 28\. Grouped Collections
* 29\. Collection Unions
* 30\. Collection Look-aheads

###### D. Routing

* 31\. Nested Route groups
* 32\. Catch-all view route
* 33\. Internal dispatch

###### E. Testing

* 34\. Environment Variables
* 35\. Run tests automatically

###### F. Miscellaneous

* 36\. Share cookies between domains
* 37\. Easy model and migration stubs
* 38\. Add Spark to an existing project
* 39\. Customize the default error page
* 40\. Conditional service providers
* 41\. Change a column name in a migration
* 42\. Checking if a view exists
* 43\. Extending the Application
* 44\. Simple cache microservice
* 45\. Using the bleeding-edge version of Laravel
* 46\. Capture queries
* 47\. Authorization without models
* 48\. Efficient file transfers with Streams
* 49\. Avoiding overflowing log files
* 50\. Pipelines

## ELOQUENT

### 1. Automatic Model Validation

```PHP
class Post extends Eloquent
{
	public staic $autoValidates = true;

	protected static $rules = [];

	protected static function boot()
	{
		parent::boot();

		// or static::creating, or static::updating
		static::saving(function($model)
		{
			if ($model::$autoValidates) {
				return $model->validate();
			}
		});
	}

	public function validate()
	{

	}
}
```

### 2. Prevent updating

```PHP
class Post extends Eloquent
{
	protected static function boot()
	{
		parent::boot();

		static::updating(function($model)
		{
			return false;
		});
	}
}
```

### 3. Conditional Relationships

```PHP
class myModel extends Model
{
	public function category()
	{
		return $this->belongsTo('myCategoryModel', 'categories_id')
			->where('users_id', Auth::user()->id);
	}
}
```

### 4. Expressive "Where" Syntax

```PHP
$products = Product::where('category', '=', 3)->get();

$products = Product::where('category', 3)->get();

$products = Product::whereCategory(3)->get();
```

### 5. Query Builder: Having Raw

```PHP
SELECT *, COUNT(*) FROM products GROUP BY category_id HAVING count(*) > 1;

DB::table('products')
	->select('*', DB::raw('COUNT(*) as products_count'))
	->groupBy('category_id')
	->having('products_count', '>', 1)
	->get();
```

### 6. Simple Date Filtering

```PHP
$q->whereDate('created_at', date('Y-m-d'));

$q->whereDay('created_at', date('d'));

$q->whereMonth('created_at', date('m'));

$q->whereYear('created_at', date('Y'));
```

### 7. Save Options

```PHP
// src/Illuminate/Database/Eloquent/Model.php
public function save(array $options = [])

// src/Illuminate/Database/Eloquent/Model.php
protected function performUpdate(Builder $query, array $options=[])
{
	if ($this->timestamps && array_get($options, 'timestamps', true))
	{
		$this->updateTimestamps();
	}
}

$product = Product::find($id);
$product->updated_at = '2015-01-01 00:00:00';
$product->save(['timestamps'=>false]);
```

### 8. Multilanguage Support

```PHP
// TODO
```

### 9. Retrieve Random Rows

```PHP
$questions = Question::orderByRaw('RAND()')->take(10)->get();
```

### 10. UUID Model Primary Key

```PHP
use Ramsey\Uuid\Uuid;

trait UUIDModel
{
	public $incrementing = false;

	protected static function boot()
	{
		parent::boot();

		static::creating(function ($model)
		{
			$key = $model->getKeyName();

			if (empty($model->{$key})) {
				$model->{$key} = (string) $model->generateNewUuid();
			}
		});
	}

	public function generateNewUuid()
	{
		return Uuid::uuid4();
	}
}
```

### 11. Ordered Relationships

```PHP
class Category extends Model
{
	public function products()
	{
		return $this->hasMany('App\Product')->orderBy('name');
	}
}
```

### 12. Simple Incrementing & Decrementing

```PHP
$customer = Customer::find($customer_id);
$loyalty_points = $customer->loyalty_points + 50;
$customer->update(['loyalty_points' => $loyalty_points]);

// adds one loyalty point
Customer::find($customer_id)->increment('loyalty_points', 50);

// subtracts one loyalty point
Customer::find($customer_id)->decrement('loyalty_points', 50);
```

### 13. Lists with Mutations

```PHP
$employees = Employee::where('branch_id', 9)->lists('name', 'id');
return view('customers.create', compact('employees'));

{!! Form::select('employee_id', $employees, '') !!}


public function getFullNameAttribute()
{
	return $this->name . ' ' . $this->surname;
}

[2015-07-19 21:47:19] local.ERROR: exception 'PDOException'...Column not found:...'full_name'

$employees = Employee::where('branch_id', 9)->get()->lists('full_name', 'id');
```

### 14. Appending Mutated Properties

```PHP
function getFullNameAttribute() 
{
	return $this->first_name . ' ' . $this->last_name;
}

class User extends Model
{
	protected $appends = ['full_name'];
}
```

### 15. Filter only rows with child rows

```PHP
class Category extends Model
{
	public function products()
	{
		return $this->hasMany('App\Product');
	}
}

public function getIndex()
{
	$categories = Category::with('products')->has('products')->get();
	return view('categories.index', compact('categories'));
}
```

### 16. Return relations on model save

```PHP
public function store()
{
	$post = new Post;
	$post->fill(Input::all());
	$post->user_id = Auth::user()->user_id;

	$post->user;

	return $post->save();
}
```

## Blade

### 17. Dynamic With

```PHP
// eloquent
Post::whereSlug('slug')->get();

// instead of
View::make('posts.index')->with('posts', $posts);

// do this
View::make('posts.index')->withPosts($posts);
```

### 18. First/Last Array Element

```PHP
// hide all but the first item
@foreach ($menu as $item)
	<div @if ($item != reset($menu)) class="hidden" @endif>
		<h2>{{ $item->title }}</h2>
	</div>
@endforeach

// apply CSS to last item only
@foreach ($menu as $item)
	<div @if ($item == end($menu)) class="no_margin" @endif>
		<h2>{{ $item->title }}</h2>
	</div>
@endforeach
```

## Collections

### 19. Arrays as Collections

```PHP
$devs = [
	['name' => 'Anouar Abdessalam', 'email' => 'dtekind@gmail.com'],
	['name' => 'Bilal Ararou', 'email' => 'have@noIdea.com'],
];

$devs = new \Illuminate\Support\Collection($devs);
```

### 20. Collection Filters

Keeps the item only if the closure returns `true`

```PHP
$customers = Customer::all();

$us_customers = $customers->filter(function($customer)
{
	return $customer->country == 'United States';
});
```

### 21. find()

```PHP
// returns a single row as a collection
$collection = Person::find([1]);

// returns multiple rows as a collection
$collection = Person::find([1, 2, 3]);
```

### 22. where()

```PHP
$collection = Person::all();

$programmers = $collection->where('type', 'programmer');
```

### 23. implode()

```PHP
$collection = Person::all();

$names = $collection->implode('first_name', ',');
```

### 24. where() & list()

```PHP
// returns a collection of first names
$collection = Person::all()->where('type', 'engineer')->lists('first_name');

// returns all meta records for user 1
$collection = WP_Meta::whereUserId(1)->get();

// returns first name meta values
$first_name = $collection->where('meta_key', 'first_name')->lists('value')[0];
```

### 25. Order belongsToMany by Pivot Table value

```PHP
class Link extends Model
{
	public function users()
	{
		return $this->belongsToMany('Phpleaks\User')->withTimestamps();
	}
}

@if ($link->users->count() > 0)
	<strong>Recently Favorited By</strong>
	@foreach ($link->users()->orderBy('link_user.created_at', 'desc')->take(15)->get() as $user)
		...
	@endforeach
@endif
```

### 26. Sorting with closures

```PHP
$sorted = $collection->sortBy(function($product, $key)
{
	return array_search($product['name'], [1=>'Bookcase', 2=>'Desk', 3=>'Chair']);
});
```

### 27. Keying arrays

Defines the 'key' for an array-as-collection (for use with e.g. `->contains`)

```PHP
$library = $books->keyBy('title');
```

### 28. Grouped Collections

```PHP
$collection = Person::all();

$grouped = $collection->groupBy('type');
```

### 29. Collection Unions

```PHP
// the point is to actually combine results from different models
$collection = new Collection;

$all = $collection->merge($programmers)->merge($critics)->merge($engineers);
```

### 30. Collection Lookaheads

```PHP
$collection = collect([1=>11, 5=>13, 12=>14, 21=>15])->getCachingIterator();

foreach ($collection as $key=>$value)
{
	dump ($collection->current() . ':' . $collection->getInnerIterator()->current());
}
```

## Routing

### 31. Nested Route Groups

```PHP
Route::group(['prefix'=> => 'account', 'as' => 'account.'], function()
{
	Route::get('login', ['as' => 'login', 'uses' => AccountController::Class.'@getLogin']);
});

<a href="{{ route('account.login') }}">Login</a>
```

### 32. Catch-all View Route

```PHP
// app/Http/routes.php
Route::group(['middleware' => 'auth'], function()
{
	Route::get('{view}', function($view)
	{
		try {
			return view($view);
		} catch (\Exception $e) {
			abort(404);
		}
	})->where('view', '.*');
});
```

### 33. Internal Dispatch

```PHP
// api controller
public funciton show(Car $car)
{
	if (Input::has('fields')) {
		// do something
	}
}

// internal request to api - fields are lost
$request = Request::create('/api/cars/' . $id . '?fields=id,color', 'GET');
$response = json_decode(Route::dispatch($request)->getContent());

// internal request to api - with fields
$originalInput = Request::input();
$request = Request::create('/api/cars' . $id . '?fields=id,color', 'GET');
Request::replace($request->input());
$response = json_decode(Route::dispatch($request)->getContent());
Request::replace($originalInput);
```

## Testing

### 34. Environmental Variables

```PHP
// phpunit.xml
<php
	<env name="APP_ENV" value="testing" />
</php>

// .env.test - add to .gitignore
TWILIO_ACCOUNT_SID=blank

// within createApplication() method of TestCase.php
if (file_exists(dirname(__DIR__) . '/.env.test')) {
	Dotenv::load(dirname(__DIR__), '.env.test');
}
```

### 35. Run tests automatically

```PHP
// gulpfile.js
var elixir = require('laravel-elixir');

mix.phpUnit();

$ gulp tdd
```

## Miscellaneous

### 36. Share Cookies Between Domains

```PHP
// app/Http/Middleware/EncryptCookies.php
protected $except = [
	'shared_cookie',
];

Cookie::queue('shared_cookie', 'my_shared_value', 10080, null, '.example.com');
```

### 37. Easy Model & Migration Stubs

```bash
$ artisan make:model Books -m
```

### 38. Add Spark to an Existing Project

Notes: Do not run `spark:install`, backup `/resources/views/home.blade.php` before running

```bash
$ composer require genealabs/laravel-sparkinstaller --dev

$ php artisan spark:upgrade

$ php artisan vendor:publish --tag=spark-full
```

```PHP
// config/app.php
Laravel\Spark\Providers\SparkServiceProvider::class,
GeneaLabs\LaravelSparkInstaller\Providers\LaravelSparkInstallerServiceProvider::class,
```

### 39. Customize the Default Error Page

```PHP
<?php namespace App\Exceptions;

use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\Debug\ExceptionHandler as SymfonyDisplayer;

class Handler extends ExceptionHandler
{
	protected function convertExceptionToResponse(Exception $e)
	{
		$debug = config('app.debug', false);
		
		return $debug
			? (new SymfonyDisplayer($debug))->createResponse($e)
			: response()->view('errors.default', ['exception' => $e], 500);
	}
}
```

### 40. Conditional Service Providers 

```PHP
// app/Providers/AppServiceProvider.php
public function register()
{
	$this->app->bind(
		\Illuminate\Contracts\Auth\Registrar::class,
		\App\Services\Registrar::class
	);

	if ($this->app->environment('production')) {
		$this->app->register(\App\Providers\ProductionErrorHandlerServiceProvider::class);
	}
	else {
		$this->app->register(\App\Providers\VerboseErrorHandlerServiceProvider::class);
	}
}
```

### 41. Change a Column Name in Migration

```PHP
$ composer require doctrine/dbal

public function up()
{
	Schema::table('users', function ($table)
	{
		$table->string('name', 50)->change();
	});
}
```

### 42. Checking if a View Exists

```PHP
if (view()->exists("emails.{$template}")) {
	// ...sending an email to the customer
}
```

### 43. Extending the Application

```PHP
// bootstrap/app.php
// replace this:
$app = new \Illuminate\Foundation\Application( realpath(__DIR__.'/../'));

// with this:
$app = new \Fantabulous\Application( realpath(__DIR__.'/../'));

// and add
<?php namespace Fantabulous;

class Application extends \Illuminate\Foundation\Application
{
	public function storagePath()
	{
		return $this->basePath.'/FantabulousStorage';
	}
}
```

### 44. Simple Caching Microservice

```PHP
class fakeApiCaller
{
	public function getResultsForPath($path)
	{
		return [
			'status' => 200,
			'body' => json_encode([
				'title' => "Results for path [$path]"
			]),
			'headers' => [
				"Content-Type" => "application/json",
			]
		];
	}
}

$app->get('{path?}', function($path)
{
	$result = Cache::remember($path, 60, function() use ($path)
	{
		return (new fakeApiCaller)->getResultsForPath($path);
	});

	return response($result['body'], $result['status'], array_only(
		$result['headers'], ['Content-Type', 'X-Pagination']
	));
})->where('path', '.*');
```

### 45. Use Bleeding Edge Version

```PHP
$ composer create-project laravel/laravel your-project-name dev-develop

// composer.json
{
	"require": {
		"php": ">=5.5.9",
		"laravel/framework": "5.2.*"
	},
	"minimum-stability": "dev"
}
```

### 46. Capture Queries

```PHP
Event::listen('illuminate.query', function($query)
{
	var_dump($query);
});

\DB::listen(function($query, $bindings, $time)
{
	var_dump( $query, $bindings, $time);

});
```

### 47. Authorization Without Models

```PHP
// app/Policies/AdminPolicy.php
class AdminPolicy
{
	public function managePages($user)
	{
		return $user->hasRole(['Administrator', 'Content Editor']);
	}
}

// app/Providers/AuthServiceProvider.php
public function boot( \Illuminate\Contracts\Auth\Access\GateContract $gate)
{
	foreach (get_class_methods(new \App\Policies\AdminPolicy) as $method) {
		$gate->define($method, \App\Policies\AdminPolicy::class . "@{$method}");
	}
	$this->registerPolicies($gate);
}

$this->authorize('managePages'); // in Controllers
@can('managePages') // in Blade
$user->can('managePages'); // via Eloquent
```

### 48. Efficient File Transfers with Streams 

```PHP
$disk = Storage::disk('s3');
$disk->put($targetFile, file_get_contents($sourceFile));

$disk = Storage::disk('s3');
$disk->put($targetFile, fopen($sourceFile, 'r+'));

$disk = Storage::disk('s3');
$stream = $disk->getDriver()->readStream($sourceFileOnS3);
file_put_contents($targetFile, stream_get_contents($stream), FILE_APPEND);

$stream = Storage::disk('s3')->getDriver()->readStream($sourceFile);
Storage::disk('sftp')->put($targetFile, $stream);
```

### 49. Avoid Overflowing Log Files

```PHP
$schedule->call(function()
{
	Storage::delete($logfile);
})->weekly();
```

### 50. Pipeline

```PHP
$result = (new \Illuminate\Pipeline\Pipeline($container))
	->send($something)
	->through('ClassOne', 'ClassTwo', 'ClassThree')
	->then(function ($something)
	{
		return 'foo';
	});
```

以上是关于markdown 50 Laravel技巧的主要内容,如果未能解决你的问题,请参考以下文章

50分钟学会Laravel 50个小技巧

jupyter notebook使用技巧--命令行模式以及在Markdown模式使用的操作

Laravel 可以验证 markdown mime 类型吗?

Markdown使用技巧总结

Laravel 5.4 更改markdown邮件的主题

Laravel5.1 搭建简单的社区--引入MarkDown