Lumen框架的所有配置项都放在配置文件.env 中。
2、访问配置值
你可以使用全局的辅助函数config来访问配置值,配置值可以通过”.”来分隔配置文件和配置项,如果配置项不存在的话则会返回默认值:
$value = config('app.timezone')
如果要在运行时设置配置值,传递一个数组到config函数:
config(['app.timezone' =>'America/Chicago'])
3、环境配置
基于应用运行环境拥有不同配置值能够给我们开发带来极大的方便,比如,我们想在本地和线上环境配置不同的缓存驱动,在Lumen中这很容易实现。
Lumen使用了Vance Lucas开发的PHP库DotEnv来实现这一目的,在新安装的Lumen中,根目录下有一个.env.example文件,如果Lumen是通过Composer安装的,那么该文件已经被重命名为.env,否则的话你要自己手动重命名该文件。
在每次应用接受请求时,.env中列出的所有变量都会被载入到PHP超全局变量$_ENV中,然后你就可以在应用中通过辅助函数env来获取这些变量值:
$debug = env('APP_DEBUG', true)
第二个传递给env函数的值是默认值,如果给定key对应的环境变量不存在则使用该默认值。
不要把.env文件提交到源码控制(svn或git等)中,因为每个使用你的应用的不同开发者或服务器可能要求不同的环境配置。
如果你是在一个团队中进行开发,你可能需要将.env.example文件随你的应用一起提交到源码控制中,通过将一些配置值以占位符的方式放置在.env.example文件中,其他开发者可以很清楚明了的知道运行你的应用需要配置哪些环境变量。
判断当前应用环境
当前应用环境通过.env文件中的配置项来 APP_ENV决定,可以通过App实例上的environment方法来访问该配置值:
$environment = app()->environment()
你也可以向environment方法中传递参数来判断当前环境是否匹配给定值,如果需要的话你甚至可以传递多个值,如果匹配的话会返回true:
if (App::environment('local')) {
// The environment is local
}
if (App::environment('local', 'staging')) {
// The environment is either local OR staging...
Laravel是一个有着美好前景的年轻框架,它的社区充满着活力,同时提供了完整而清晰的文档,而且为快速、安全地开发现代应用提供了必要的功能。2011年,Taylor Otwell首次将Laravel带给这个世界,彼时,Laravel就是一个全新且现代的框架。Laravel基于MVC架构,可以满足诸如事件处理、用户身份验证等各种需求,同时通过包管理实现模块化和可扩展的代码,并且对数据库管理有着健壮的支持。
不管是专家还是新手,一旦接触到Laravel,都会有相见恨晚之感——这正是你在为PHP项目寻找的框架。本文我们将讨论为什么Laravel会成为最成功最流行的PHP框架。
模块化&可扩展性
Laravel是模块化和可扩展的,你可以在包含超过5500个程序包的Packalyst中找到你想要添加的任何代码。
微服务&API
Lumen是一个由Laravel衍生的专注于性能的微框架。使用Lumen提供的高性能API你可以更加简单快速地开发微型项目。Lumen使用最小的配置集成了Laravel的所有重要特性,你可以通过将代码复制到Laravel项目来实现框架的完整迁移。
<?php
$app->get('/', function() {
return view('lumen')
})
$app->post('framework/{id}', function($framework) {
$this->dispatch(new Energy($framework))
})
HTTP路由
Laravel拥有类似于Ruby on Rails的快速高效的路由系统。它可以让用户通过在浏览器上输入路径的方式让应用程序的各部分相关联。
Route::get('/', function () {
return 'Hello World'
})
HTTP中间件
Route::get('/', function () {
return 'Hello World'
})
Laravel可以通过中间件对应用进行保护——中间件会处理分析和过滤到达服务器的HTTP请求。你可以使用中间件来验证注册用户、避免跨站脚本攻击(XSS)以及其它安全问题。
<?php
namespace App\Http\Middleware
use Closure
class OldMiddleware {
public function handle($request, Closure $next) {
if ($request->input('age') <= 200) {
return redirect('home')
}
return $next($request)
}
}
缓存
Laravel提供了健壮的缓存系统,使用缓存可以让应用加载地更加快速,从而带来更好的用户体验。
Cache::extend('mongo', function($app) {
return Cache::repository(new MongoStore)
})
身份验证
安全是至关重要的。Laravel自带对本地用户的身份验证,并可以使用“remember” 选项来记住用户。此外你还可以引入一些额外参数,例如是否是活跃用户。
if (Auth::attempt(['email' =>$email, 'password' =>$password, 'active' =>1 ], $remember)) {
// The user is being remembered...
}
集成Stripe
Laravel Cashier可以满足你开发支付系统过程中所需要的任何需求。除此之外,它还同步并集成了用户身份验证系统。所以,你不再需要担心如何将计费系统集成到开发中了。
$user = User::find(1)
$user->subscription('monthly')->create($creditCardToken)
任务自动化
Elixir是一个让我们可以使用Gulp定义任务的Laravel API,我们可以使用Elixir定义预处理器来压缩CSS 和JavaScript。
elixir(function(mix) {
mix.browserify('main.js')
})
加密
一个安全的应用应该做到可以对数据进行加密。在Laravel中,可以使用OpenSSL和AES-256-CBC加密算法来满足你所有的加密需求。此外,所有的加密值都通过认证码进行签名以避免加密信息被篡改。
use Illuminate\Contracts\Encryption\DecryptException
try {
$decrypted = Crypt::decrypt($encryptedValue)
} catch (DecryptException $e) {
//
}
事件处理
Laravel应用中对事件的定义、记录和监听都非常便捷。服务提供者EventServiceProvider中的listen属性包含了应用中的所有事件列表。
protected $listen = [
'App\Events\PodcastWasPurchased' =>[
'App\Listeners\EmailPurchaseConfirmation',
],
]
分页
在Laravel中分页非常简单,因为它能够根据用户在浏览器中的当前页生成一系列分页链接。
<?php
namespace App\Http\Controllers
use DB
use App\Http\Controllers\Controller
class UserController extends Controller {
public function index() {
$users = DB::table('users')->paginate(15)
return view('user.index', ['users' =>$users])
}
}
对象关系映射(ORM)
Laravel包含了一个数据库处理层,其中的对象关系映射被称作Eloquent。另外这个对象关系映射也适用于PostgreSQL。
$users = User::where('votes', '>', 100)->take(10)->get()
foreach ($users as $user) {
var_dump($user->name)
}
单元测试
单元测试的开发是一个耗费大量时间的任务,但是它却保证了我们的应用能够正常工作,不出问题。Laravel使用PHPUnit进行单元测试。
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware
use Illuminate\Foundation\Testing\DatabaseTransactions
class ExampleTest extends TestCase {
public function testBasicExample() {
$this->visit('/')->see('Laravel 5')->dontSee('Rails')
}
}
待办事项清单(Queue)
Laravel提供了在后台使用待办事项清单(to do list)处理复杂、漫长流程的选择,好吧,其实就是队列,队列可以让我们异步处理某些流程而不需要用户在加载页面时长时间的等待。
Queue::push ( new SendEmail ( $ message ))
做过一个E应用,使用lumen框架,和你的思路是一样的,新用户点进去就自动授权注册应用,数据存到我们自己的数据库中,不依赖钉钉,我们还同步了部门信息,如果粘贴复制和下面的那个同学一样,看上去你也会觉得懵,方法都是封装好了的。
建议你这样试试看:
获取AccessToken:
后端通过corpid,corpsecret请求接口gettoken?corpid=id&corpsecret=secrect获取AccessToken
获取钉钉用户userid:
前端需要相应的处理,携带authCode请求,加上AccessToken这两个参数请求接口/user/getuserinfo?access_token=access_token&code=authCode这个
获取钉钉用户详情:
使用access_token和上一步的钉钉userid 请求接口 /user/get?access_token=ACCESS_TOKEN&userid=
插入钉钉用户的数据到你的 数据库中
我们这样做的:
/**
* 钉钉免登陆获获取用信息
* @param $authCode
* @param $url
* @return array
*/
static function outhLogin($authCode, $url)
{
if (empty($authCode) || empty($url)) {
return self::returnError('1101', self::$errorArray['1101'])
}
$accessToken = ComponentDingtalk::getPcAccessToken()
if ($accessToken['code']) {
self::logError(__CLASS__ . '->' . __FUNCTION__, '获取access_token失败')
return self::returnError('1102', self::$errorArray['1102'])
}
$dingUserId = ComponentDingtalk::getDingUserid($accessToken['data'], $authCode)
if ($dingUserId['code']) {
self::logError(__CLASS__ . '->' . __FUNCTION__, '用户userid获取失败(调用钉钉API)')
return self::returnError('1103', self::$errorArray['1103'])
}
$dinguserInfo = ComponentDingtalk::getDingUserInfo($accessToken['data'], $dingUserId['data'])
if ($dinguserInfo['code']) {
self::logError(__CLASS__ . '->' . __FUNCTION__, '用户信息获取失败(调用钉钉API)')
return self::returnError('1104', self::$errorArray['1004'])
}
$userInfo = $dinguserInfo['data']
return self::transaction(function () use ($accessToken, $userInfo, $url) {
if (\count($userInfo['department']) >1) {
$departIdArr = []
$departNameArr = []
for ($i = 0, $iMax = \count($userInfo['department'])$i <$iMax$i++) {
$departInfo[$i] = ServerDepartment::getByDdDepartid($userInfo['department'][$i])
$departIdArr[] = $departInfo[$i]['id']
$departNameArr[] = $departInfo[$i]['name']
}
$depart['id'] = implode(',', $departIdArr)
$depart['name'] = implode(',', $departNameArr)
} else {
$ddDepartmentId = implode(',', $userInfo['department'])
$depart = ServerDepartment::getByDdDepartid($ddDepartmentId)
}
//插入用户
$user = ServerEmployee::getByDdUserid($userInfo['userid'])
if ($user &&$user['status'] == 2) {
return self::returnError('1105', self::$errorArray['1105'])
}
if (empty($user)) {
$roleId = 0
$departId = $depart['id']
$name = $userInfo['name']
$mobile = $userInfo['mobile']
$departName = $depart['name']
$position = $userInfo['position']
$ddUserid = $userInfo['userid']
$ddStatus = $userInfo['active'] ? 1 : 2
$ddInfo = json_encode($userInfo, JSON_UNESCAPED_UNICODE)
$tokenOverAt = (int)(time() + $_ENV['PROJECT_apiAppTokenOverTime'])
$token = self::_createToken($userInfo['userid'], $tokenOverAt)
$status = 1
$userId = ServerEmployee::insert($roleId, $departId, $name, $mobile, $departName, $position, $ddUserid, $ddStatus, $ddInfo, $token, $tokenOverAt, $status)
if (!$userId) {
self::logError(__CLASS__ . '->' . __FUNCTION__, '用户初始化创建失败')
return self::returnError('1106', self::$errorArray['1106'])
}
}
$userId = $userId ?? $user['id']
// 更新Token
$id = $userId
$roleId = $user['roleId']
$departId = $depart['id']
$name = $userInfo['name']
$mobile = $userInfo['mobile']
$departName = $depart['name']
$position = $userInfo['position']
$ddUserid = $userInfo['userid']
$ddStatus = $userInfo['active'] ? 1 : 2
$ddInfo = json_encode($userInfo, JSON_UNESCAPED_UNICODE)
$tokenOverAt = (int)(time() + $_ENV['PROJECT_apiAppTokenOverTime'])
$token = self::_createToken($userInfo['userid'], $tokenOverAt)
$status = 1
$updateParams = ServerEmployee::update($id, $roleId, $departId, $name, $mobile, $departName, $position, $ddUserid, $ddStatus, $ddInfo, $token, $tokenOverAt, $status)
if (!$updateParams) {
self::logError(__CLASS__ . '->' . __FUNCTION__, '用户信息更新失败' . json_encode($updateParams, JSON_UNESCAPED_UNICODE) . '/' . json_encode([$id, $roleId, $departId, $name, $mobile, $depart, $position, $ddUserid, $ddStatus, $ddInfo, $token, $tokenOverAt, $status]))
return self::returnError('1107', self::$errorArray['1107'])
}
// 前端的配置信息
// 获取jsTicket
$jsTicket = ComponentDingtalk::getPcJsTicket($accessToken['data'])
if ($jsTicket['code']) {
self::logError(__CLASS__ . '->' . __FUNCTION__, '获取jsTicket失败(调用钉钉API)')
return self::returnError('1111', self::$errorArray['1111'])
}
// 组装签名数据
$curUrl = $url
$nonceStr = uniqid('', true)
$agentId = $_ENV['PROJECT_ddInterfaceAgentID']
$timeStamp = time()
$corpId = $_ENV['PROJECT_ddInterfaceCorpId']
$signature = ComponentDingtalk::getSign($jsTicket['data'], $nonceStr, $timeStamp, $curUrl)
$config = array(
'url' =>urldecode($curUrl),
'nonceStr' =>$nonceStr,
'agentId' =>$agentId,
'timeStamp' =>$timeStamp,
'corpId' =>$corpId,
'signature' =>$signature
)
// 获取当前角色的权限
$roleInfo = ServerRole::getById($roleId)
// 当前用户的顶级部门(不含根部门)
$departInfo = ServerDepartment::getById($departId)
if ($departInfo['parentid'] == 1) { // 二级部门(总经办)
$departRootId = $departId
$departRootName = $departName
} else {
$sonDepart = ServerDepartment::getById($departInfo['parentid'])//分组
if ($sonDepart['parentid'] == 1) {
$departRootId = $sonDepart['id']
$departRootName = $sonDepart['name']
} else {
$grandsonDepart = ServerDepartment::getById($sonDepart['parentid'])//部门
if ($grandsonDepart['parentid'] == 1) {
$departRootId = $grandsonDepart['id']
$departRootName = $grandsonDepart['name']
} else {
$grandchildDepart = ServerDepartment::getById($grandsonDepart['parentid'])//分公司
$departRootId = $grandchildDepart['id']
$departRootName = $grandchildDepart['name']
}
}
}
$company = ServerDepartment::get(['parentid' =>0, 'dd_departid' =>1])
return self::returnSuccess(array(
'id' =>$userId,
'name' =>$name,
'token' =>$token,
'tokenOverAt' =>$tokenOverAt,
'config' =>$config,
'power' =>$roleInfo['power'] ?? '',
'departId' =>$departId,
'departName' =>$departName,
'departRootId' =>$departRootId,
'departRootName' =>$departRootName,
'company' =>$company['name'],
))
}, function (\Exception $e) {
echo $e->getMessage()
self::logError(__CLASS__ . '->' . __FUNCTION__, $e->getMessage())
return self::returnError('1108', self::$errorArray['1108'])
})
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)