[ Laravel 5.3 文档 ] 官方包 —— Laravel Cashier

   2016-10-17 0
核心提示:1、简介LaravelCashier为通过Stripe实现订阅支付服务提供了一个优雅的流式接口。它封装了几乎所有你恐惧编写的样板化的订阅支付代码。除了基本的订阅管理外,Cashier 还支持处理优惠券、订阅升级/替换、订阅“数量”、取消宽限期,甚至生成PDF发票。注:如果

1、简介

Laravel Cashier为通过 Stripe实现订阅支付服务提供了一个优雅的流式接口。它封装了几乎所有你恐惧编写的样板化的订阅支付代码。除了基本的订阅管理外,Cashier 还支持处理优惠券、订阅升级/替换、订阅“数量”、取消宽限期,甚至生成 PDF 发票。

注:如果你只需要一次性支付,并不提供订阅,就不应该使用 Cashier,而是直接使用 Stripe 和Braintree SDK。

2、配置

Stripe

Composer

首先,添加 Cashier 包到 composer.json 文件并运行  composer update 命令:

"laravel/cashier": "~7.0"

服务提供者

接下来,在 config/app.php 配置文件中注册服务提供者: Laravel\Cashier\CashierServiceProvider

数据库迁移

使用 Cashier 之前,我们需要准备好数据库。我们需要添加一个字段到 users 表,还要创建新的  subscriptions 表来处理所有用户订阅:

Schema::table('users', function ($table) {
    $table->string('stripe_id')->nullable();
    $table->string('card_brand')->nullable();
    $table->string('card_last_four')->nullable();
    $table->timestamp('trial_ends_at')->nullable();
});

Schema::create('subscriptions', function ($table) {
    $table->increments('id');
    $table->integer('user_id');
    $table->string('name');
    $table->string('stripe_id');
    $table->string('stripe_plan');
    $table->integer('quantity');
    $table->timestamp('trial_ends_at')->nullable();
    $table->timestamp('ends_at')->nullable();
    $table->timestamps();
});

创建好迁移后,只需简单运行 migrate 命令,相应修改就会更新到数据库。

Billable 模型

接下来,添加 Billable trait 到  User 模型类,这个trait提供了多个方法以便执行常用支付任务,例如创建订阅、使用优惠券以及更新信用卡信息:

use Laravel\Cashier\Billable;

class User extends Authenticatable
{
    use Billable;
}

API Key

最后,在配置文件 config/services.php 中配置 Stripe 的key,你可以在Stripe官网个人中心的控制面板中获取这些Stripe API key信息:

'stripe' => [
    'model'  => App\User::class,
    'secret' => env('STRIPE_API_SECRET'),
],

Braintree

Braintree 注意事项

对于很多操作,Stripe 和 Braintree 实现的 Cashier 功能都是一样的,两者都提供了通过信用卡进行订阅支付的功能,但是 Braintree 还支持通过 PayPal 支付。不过,Braintree 也缺失一些 Stripe 支持的功能,在决定使用 Stripe 还是 Braintree 之前,需要考虑以下几点:

  • Braintree 支持 PayPal 而 Stripe 不支持;
  • Braintree 不支持 incrementdecrement 方法,这个是 Braintree 级别的限制,不是 Cashier 级别的;
  • Braintree 不支持基于百分比的折扣,这个也是 Braintree 级别的限制,不是 Cashier 级别的

Composer

首先,添加针对 Braintree 的 Cashier扩展包到 composer.json 文件并运行 composer update 命令:

"laravel/cashier-braintree": "~2.0"

服务提供者

接下来,在配置文件 config/app.php 中注册服务提供者 Laravel\Cashier\CashierServiceProvider

计划信用优惠券

在使用基于 Braintree 的 Cashier 之前,需要在 Braintree 的控制面板中定义一个 plan-credit 折扣,这个折扣将会用于从年到月或者从月到年支付的优惠额度比例分配。

配置在 Braintree 控制面板中的这个折扣值可以是你希望的任何值,Cashier 将会在每次使用优惠券的时候通过自定义的值来重写这个默认定义的值。该优惠券之所以是必须的是因为 Braintree 不支持本地根据订阅时长进行优惠额度的按比例分配。

数据库迁移

使用 Cashier 之前,需要准备好数据库。我们需要添加额外的字段到 users 表并创建一个新的 subscriptions 表用于存放所有用户订阅:

Schema::table('users', function ($table) {
    $table->string('braintree_id')->nullable();
    $table->string('paypal_email')->nullable();
    $table->string('card_brand')->nullable();
    $table->string('card_last_four')->nullable();
    $table->timestamp('trial_ends_at')->nullable();
});

Schema::create('subscriptions', function ($table) {
    $table->increments('id');
    $table->integer('user_id');
    $table->string('name');
    $table->string('braintree_id');
    $table->string('braintree_plan');
    $table->integer('quantity');
    $table->timestamp('trial_ends_at')->nullable();
    $table->timestamp('ends_at')->nullable();
    $table->timestamps();
});

迁移被创建之后,只需要执行Artisan命令 migrate 即可。

Billable模型

接下来,添加 Billable trait到模型定义:

use Laravel\Cashier\Billable;

class User extends Authenticatable
{
    use Billable;
}

API Key

接下来,需要在配置文件 services.php 中配置如下选项:

'braintree' => [
    'model'  => App\User::class,
    'environment' => env('BRAINTREE_ENV'),
    'merchant_id' => env('BRAINTREE_MERCHANT_ID'),
    'public_key' => env('BRAINTREE_PUBLIC_KEY'),
    'private_key' => env('BRAINTREE_PRIVATE_KEY'),
],

然后你需要在服务提供者 AppServiceProviderboot 方法中添加对 Braintree SDK 的调用:

\Braintree_Configuration::environment(config('services.braintree.environment'));
\Braintree_Configuration::merchantId(config('services.braintree.merchant_id'));
\Braintree_Configuration::publicKey(config('services.braintree.public_key'));
\Braintree_Configuration::privateKey(config('services.braintree.private_key'));

货币 配置

Cashier 默认货币是美元(USD),你可以在某个服务提供者的 boot 方法中通过调用 Cashier::useCurrency 方法来更改默认的货币, useCurrency 方法接收两个字符串参数:货币及货币符号:

use Laravel\Cashier\Cashier;

Cashier::useCurrency('eur', '€');

3、订阅

创建订阅

要创建一个订阅,首先要获取一个账单模型的实例,通常是 App\User 的实例。获取到该模型实例之后,你可以使用 newSubscription 方法来创建该模型的订阅:

$user = User::find(1);
$user->newSubscription('main', 'monthly')->create($creditCardToken);

第一个传递给 newSubscription 方法的参数是该订阅的名字,如果应用只有一个订阅,可以将其称作  mainprimary ,第二个参数用于指定用户订阅的 Stripe/Braintree 计划,该值对应 Stripe 或 Braintree 中相应计划的 id。

create 方法会自动创建这个 Stripe 订阅,同时更新数据库中 Stripe 的客户 ID(即  users 表中的  stripe_id )和其它相关的账单信息。

额外的用户信息

如果你想要指定额外的客户信息,你可以将其作为第二个参数传递给 create 方法:

$user->newSubscription('main', 'monthly')->create($creditCardToken, [
    'email' => $email,
]);

要了解更多 Stripe 支持的字段,可以查看 Stripe 关于 创建消费者的文档 或者相应的 Braintree文档

优惠券

如果你想要在创建订阅的时候使用优惠券,可以使用 withCoupon 方法:

$user->newSubscription('main', 'monthly')
     ->withCoupon('code')
     ->create($creditCardToken);

检查订阅状态

用户订阅你的应用后,你可以使用各种便利的方法来简单检查订阅状态。首先,如果用户有一个有效的订阅,则 subscribed 方法返回 true ,即使订阅现在处于试用期:

if ($user->subscribed('main')) {
    //
}

subscribed 方法还可以用于路由中间件,基于用户订阅状态允许你对路由和控制器的访问进行过滤:

public function handle($request, Closure $next){
    if ($request->user() && ! $request->user()->subscribed('main')) {
        // This user is not a paying customer...
        return redirect('billing');
    }

    return $next($request);
}

如果你想要判断一个用户是否还在试用期,可以使用 onTrial 方法,该方法对于还处于试用期的用户显示警告信息很有用:

if ($user->->subscription('main')->onTrial()) {
    //
}

subscribedToPlan 方法可用于判断用户是否基于 Stripe/Braintree ID 订阅了给定的计划,在本例中,我们会判断用户的 main 订阅是否订阅了 monthly 计划:

if ($user->subscribedToPlan('monthly', 'main')) {
    //
}

已取消的订阅状态

要判断用户是否曾经是有效的订阅者,但现在取消了订阅,可以使用 cancelled 方法:

if ($user->subscription('main')->cancelled()) {
    //
}

你还可以判断用户是否曾经取消过订阅,但现在仍然在“宽限期”直到完全失效。例如,如果一个用户在3月5号取消了一个实际有效期到3月10号的订阅,该用户处于“宽限期”直到3月10号。注意 subscribed 方法在此期间仍然返回  true

if ($user->subscription('main')->onGracePeriod()) {
    //
}

修改计划

用户订阅应用后,偶尔想要改变到新的订阅计划,要将用户切换到新的订阅, 传递计划标识到 swap 方法:

$user = App\User::find(1);
$user->subscription('main')->swap('provider-plan-id');

如果用户在试用,试用期将会被维护。还有,如果订阅存在多个,数量也可以被维护。

如果你想要切换计划并取消用户所在的所有试用期,你可以使用 skipTrial 方法:

$user->subscription('main')
     ->skipTrial()
     ->swap('provider-plan-id');

订阅数量

注:只有 Stripe 版本的 Cashier 支持订阅数量,Braintree 没有提供类似 Stripe “ 数量 ”这样的特性。

有时候订阅也会被数量影响,例如,应用中每个账户每月需要付费$10,要简单增加或减少订阅数量,使用 incrementQuantity 和  decrementQuantity 方法:

$user = User::find(1);

$user->subscription('main')->incrementQuantity();

// Add five to the subscription's current quantity...
$user->subscription('main')->incrementQuantity(5);

$user->subscription('main')->decrementQuantity();

// Subtract five to the subscription's current quantity...
$user->subscription('main')->decrementQuantity(5);

你也可以使用 updateQuantity 方法指定数量:

$user->subscription('main')->updateQuantity(10);

想要了解更多订阅数量信息,查阅相关 Stripe文档

订阅税金

要指定用户支付订阅的税率,实现账单模型的 taxPercentage 方法,并返回一个在0到100之间的数值,不要超过两位小数:

public function taxPercentage() {
    return 20;
}

这将使你可以在模型基础上使用税率,对跨越不同国家不同税率的用户很有用。

注: taxPercentage 方法只能用于订阅支付,如果你使用 Cashier 生成一次性账单,需要手动指定税率。

取消订阅

要取消订阅,可以调用用户订阅上的 cancel 方法:

$user->subscription('main')->cancel();

当订阅被取消时,Cashier 将会自动设置数据库中的 ends_at 字段。该字段用于了解  subscribed 方法什么时候开始返回  false 。例如,如果客户3月1号份取消订阅,但订阅直到3月5号才会结束,那么  subscribed 方法继续返回  true 直到3月5号。

你可以使用 onGracePeriod 方法判断用户是否已经取消订阅但仍然在“宽限期”:

if ($user->subscription('main')->onGracePeriod()) {
    //
}

如果你想要立即取消订阅,调用用户订阅上的方法 cancelNow 即可:

$user->subscription('main')->cancelNow();

恢复订阅

如果用户已经取消订阅但想要恢复该订阅,可以使用 resume 方法,前提是该用户必须在宽限期内:

$user->subscription('main')->resume();

如果该用户取消了一个订阅然后在订阅失效之前恢复了这个订阅,则不会立即支付该账单,取而代之的,他们的订阅只是被重新激活,并回到正常的支付周期。

更新信用卡

updateCard 方法可用于更新用户的信用卡信息,该方法接收一个 Stripe 令牌并设置新的信用卡作为支付源:

$user->updateCard($creditCardToken);

4、订阅试用期

带信用卡信息

如果你想要在提供给用户试用期的同时预先收集支付方式信息,可以在创建订阅的时候使用 trialDays 方法:

$user = User::find(1);

$user->newSubscription('main', 'monthly')
     ->trialDays(10)
     ->create($creditCardToken);

该方法会在数据库订阅记录上设置试用期结束日期,以便告知Stripe/Braintree在此之前不要计算用户的账单信息。

注:如果用户的订阅没有在试用期结束之前取消,则会在试用期结束时立即支付,所以要确保通知用户试用期结束时间。

可以使用用户实例或订阅实例上的 onTrial 方法判断用户是否处于试用期,下面两个例子作用是等价的:

if ($user->onTrial('main')) {
    //
}

if ($user->subscription('main')->onTrial()) {
    //
}

不带信用卡信息

如果你不想在提供试用期的时候收集用户支付方式信息,只需设置用户记录的 trial_ends_at 字段为期望的试用期结束日期即可,这通常在用户注册期间完成:

$user = User::create([
    // Populate other user properties...
    'trial_ends_at' => Carbon::now()->addDays(10),
]);

注:确保已添加 trial_ends_at 日期修改器到模型定义。

Cashier 将这种类型的试用期看作“ 一般体验”,因为这种使用并没有附加到任何已经在的订阅,如果当前日期没有超过 trial_ends_at 的值, User 实例上的 onTrial 方法将返回 true

if ($user->onTrial()) {
    // User is within their trial period...
}

如果你想要知道用户是否在“一般”试用期并且还没有创建实际的订阅还可以使用 onGenericTrial 方法:

if ($user->onGenericTrial()) {
    // User is within their "generic" trial period...
}

一旦你准备好为用户创建实际的订阅,可以使用 newSubscription 方法:

$user = User::find(1);

$user->newSubscription('main', 'monthly')->create($creditCardToken);

5、处理 Stripe Webhooks

Stripe 和 Braintree 都可以通过 webhooks 通知应用各种事件,要处理 Stripe webhooks,需要定义一个指向 Cashier webhook 控制器的路由,这个控制器将会处理所有输入 webhook 请求并将它们分发到合适的控制器方法:

Route::post(
    'stripe/webhook',
    '\Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook'
);

注:注册好控制器后,还要在Stripe控制面板中配置webhook URL。

默认情况下,这个控制器将会自动对支付失败次数(这个次数可以在 Stripe 设置中定义)过多的订阅进行取消;此外,我们很快会发现,你可以扩展这个控制器来处理任何你想要处理的 webhook 事件。

Webhooks & CSRF 防护

由于Stripe webhook需要绕开 Laravel 的 CSRF 保护,所以需要将其罗列到 VerifyCsrfToken 中间件的排除列表或者将其置于 web 中间件组之外:

protected $except = [
    'stripe/*',
];

定义Webhook事件处理器

Cashier 会基于支付失败次数自动取消订阅,但是如果你想要处理额外的Stripe webhook事件,扩展Webhook控制器即可。定义的方法名需要与Cashier约定的格式保持一致,特别是方法名需要以 handle 开头并且是想要处理的Stripe webhook的驼峰格式。例如,如果你想要处理  invoice.payment_succeeded webhook,则需要添加一个 handleInvoicePaymentSucceeded 方法到控制器:

<?php

namespace App\Http\Controllers;

use Laravel\Cashier\Http\Controllers\WebhookController as CashierController;

class WebhookController extends CashierController
{
    /**
     * Handle a Stripe webhook.
     *
     * @param  array  $payload
     * @return Response
     */
    public function handleInvoicePaymentSucceeded($payload)
    {
        // Handle The Event
    }
}

失败的订阅

如果用户的信用卡过期怎么办?不用担心——Cashier webhook控制器可以轻松为你取消该用户的订阅,正如上面所提到的,你所需要做的只是将路由指向该控制器:

Route::post(
    'stripe/webhook',
    '\Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook'
);

就是这样,失败的支付将会被控制器捕获和处理,该控制器将会在 Stripe 判断订阅支付失败次数(通常是3次)达到上限时取消该用户的订阅。

6、处理Braintree Webhooks

Stripe 和 Braintree 都可以通过 webhooks 通知应用各种事件,要处理 Braintree webhooks,需要定义一个指向 Cashier webhook 控制器的路由,这个控制器将会处理所有输入 webhook 请求并将它们分发到合适的控制器方法:

Route::post(
    'braintree/webhook',
    '\Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook'
);

注:注册好控制器后,还要在 Braintree 控制面板中配置 webhook URL。

默认情况下,这个控制器将会自动对支付失败次数(这个次数可以在 Braintree 设置中定义)过多的订阅进行取消;此外,我们很快会发现,你可以扩展这个控制器来处理任何你想要处理的 webhook 事件。

Webhooks & CSRF 防护

由于 Braintree webhook 需要绕开 Laravel 的 CSRF 保护,所以需要将其罗列到 VerifyCsrfToken 中间件的排除列表或者将其置于 web 中间件组之外:

protected $except = [
    'braintree/*',
];

定义Webhook事件处理器

Cashier 会基于支付失败次数自动取消订阅,但是如果你想要处理额外的 Braintree webhook 事件,扩展 Webhook 控制器即可。定义的方法名需要与 Cashier 约定的格式保持一致,特别是方法名需要以 handle 开头并且是想要处理的Braintree webhook的驼峰格式。例如,如果你想要处理  dispute_opened webhook,则需要添加一个 handleDisputeOpened 方法到控制器:

<?php

namespace App\Http\Controllers;

use Braintree\WebhookNotification;
use Laravel\Cashier\Http\Controllers\WebhookController as CashierController;

class WebhookController extends CashierController
{
    /**
     * Handle a Braintree webhook.
     *
     * @param  WebhookNotification  $webhook
     * @return Response
     */
    public function handleDisputeOpened(WebhookNotification $notification)
    {
         // Handle The Event
    }
}

失败的订阅

如果用户的信用卡过期怎么办?不用担心——Cashier webhook控制器可以轻松为你取消该用户的订阅,正如上面所提到的,你所需要做的只是将路由指向该控制器:

Route::post(
    'braintree/webhook',
    '\Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook'
);

就是这样,失败的支付将会被控制器捕获和处理,该控制器将会在 Braintree 判断订阅支付失败次数(通常是3次)达到上限时取消该用户的订阅。不要忘记在 Braintree 控制面板中配置webhook URI。

7、一次性支付

基本支付

注:使用 Stripe 时, charge 方法可以接收应用所使用货币对应的最小单位金额,但是使用 Braintree 时,必须传递完整的美元金额到 charge 方法。

如果你想要使用订阅客户的信用卡一次性结清账单,可以使用账单模型实例上的 charge 方法:

// Stripe Accepts Charges In Cents...
$user->charge(100);

// Braintree Accepts Charges In Dollars...
$user->charge(1);

charge 方法接收一个数组作为第二个参数,允许你传递任何你想要传递的底层 Stripe/Braintree 账单创建参数,创建账单时我们可以参考Stripe或者Braintree文档提供的可用选项:

$user->charge(100, [
    'custom_option' => $value,
]);

如果支付失败 charge 方法将抛出异常,如果支付成功,该方法会返回完整的 Stripe / Braintree 响应:

try {
    $response = $user->charge(100);
} catch (Exception $e) {
    //
}

带发票的支付

有时候你需要创建一个一次性支付并且同时生成对应发票以便为用户提供一个PDF单据, invoiceFor 方法可以帮助我们实现这个需求。例如,让我们为用户的“一次性费用”生成一张$5.00的发票:

// Stripe Accepts Charges In Cents...
$user->invoiceFor('One Time Fee', 500);

// Braintree Accepts Charges In Dollars...
$user->invoiceFor('One Time Fee', 5);

该单据会通过用户信用卡立即支付, invoiceFor 方法还可以接收一个数组作为第三个参数,从而允许你传递任意你希望的选项到底层 Stripe/Braintree 支付创建:

$user->invoiceFor('One Time Fee', 500, [
    'custom-option' => $value,
]);

注: invoiceFor 方法会0创建一个对失败支付进行重试的 Stripe 单据,如果你不想要单据重试失败的支付,需要在首次支付失败后使用 Stripe API 关闭它们。

8、发票

你可以使用 invoices 方法轻松获取账单模型的发票数组:

$invoices = $user->invoices();

// Include pending invoices in the results...
$invoices = $user->invoicesIncludingPending();

当列出客户发票时,你可以使用发票的辅助函数来显示相关的发票信息。例如,你可能想要在表格中列出每张发票,从而方便用户下载它们:

<table>
    @foreach ($invoices as $invoice)
    <tr>
        <td>{{ $invoice->date()->toFormattedDateString() }}</td>
        <td>{{ $invoice->total() }}</td>
        <td><a href=http://www.tuicool.com/articles/"/user/invoice/{{ $invoice->id }}">Download
    
    @endforeach

生成PDF发票

在生成PDF分票之前,需要安装 PHP 库 dompdf

composer require dompdf/dompdf

然后,在路由或控制器中,使用 downloadInvoice 方法生成发票的 PDF 下载,该方法将会自动生成相应的 HTTP 响应发送下载到浏览器:

use Illuminate\Http\Request;

Route::get('user/invoice/{invoice}', function (Request $request, $invoiceId) {
    return $request->user()->downloadInvoice($invoiceId, [
        'vendor'  => 'Your Company',
        'product' => 'Your Product',
    ]);
});
 
标签: Laravel
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • nginx 各类网站设置 (laravel , thinkphp , nod
    基础部分设置[root@centos ~]# vim /opt/nginx/conf/nginx.confuser www www;worker_processes auto;pid logs/nginx.pid;worker_rlimit_nofile 100000;events {use epoll;multi_accept on;worker_connections 65535 ;}http {include mime.types;default_type
    02-09
  • PHP trait 特性在 Laravel 中的使用个人心得
    trait 是在PHP5.4中为了方便代码复用的一种实现方式,但目前我在看的的PHP项目中较少看的有程序员去主动使用这个实现方式,在laravel中有很多 trait 的使用,关于trait 在 laravel 的使用请参看 Laravel 在哪些地方用了 trait?我曾在 Laravel 中大型项目面向
    02-09
  • 让我们用 laravel-mix 为 TypeScript 和 Sass
    介绍前端编译TypeScript、Sass、模板引擎等时经常用到Gulp和webpack。这是我个人的印象,但它们似乎都难以管理,因为它们的描述往往复杂而冗长。我不想积极进行,因为我要担心加载器的顺序并且有很多配置选项,我必须花时间去了解它们。我想推荐那里laravel
  • PHP Laravel软删除的实现方法介绍
    用Laravel 自带的 Eloquent ORM 来实现软删除。首先在数据迁移文件中添加删除时间字段./database/migrations/2014_10_12_000000_create_users_table.php?phpuse Illuminate\Database\Migrations\Migration;use Illuminate\Database\Schema\Blueprint;use Illu
  • Laravel中如何使用PHP的装饰器模式 php laravel
    本文小编为大家详细介绍“Laravel中如何使用PHP的装饰器模式”,内容详细,步骤清晰,细节处理妥当,希望这篇“Laravel中如何使用PHP的装饰器模式”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。装饰器模式定义:它可以帮助您在
    02-08 laravelphp
  • PHP laravel使用自定义邮件类实现发送邮件
    PHP laravel使用自定义邮件类实现发送邮件
    当登录邮箱为腾讯企业邮箱的时候。Phpmailer发送邮件就不好用了,具体哪里不好用,我没真没找到。但是,邮件得发啊,怎么办呢?我这里搞了一个自定义的发送邮件类,腾讯企业邮箱也可用。但是,邮件发送失败,不会返回报错信息,这个可能是有点坑。源码如下:?
  • 详解PHP laravel中的加密与解密函数
    目录一:简介二:配置三:使用加密/解密1:加密2:不使用序列化进行加密3:解密Laravel为我们提供了完整的加密方法及加密模式。我之前一般在加密的时候使用的是我自己写的加密函数,但是这个玩意,有的位置还是不太使用,当然,破解的话,基本上也是不可能的
  • PHP laravel缓存cache机制详解
    目录一、访问多个缓存存储二、从缓存中获取数据1.获取数据并设置默认值2.检查缓存项是否存在3.数值增加/减少4.获取存储5.获取删除三、缓存中存储数据1.获取存储数据2.缓存不存在时存储数据3.永久存储数据四、从缓存中移除数据Laravel中的cache为我们提供了三
  • PHP laravel实现导出PDF功能
    PHP laravel实现导出PDF功能
    目录一、laravel-tcpdf二、tcpdf三、TCPDF解决保存中文文件名的方法补充一、laravel-tcpdf导出PDF文件Laravel框架为我们集成了一个插件tcpdf。下载地址:https://github.com/elibyy/tcpdf-laravel然后使用composer进行安装就可以了。具体安装过程,请查看文末
  • PHP laravel缓存cache机制怎么实现
    今天小编给大家分享一下PHP laravel缓存cache机制怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Laravel中的cache为我们
点击排行