文章來自:zhuanlan.zhihu.com/p/340742883
好記性不如爛筆頭,學習php開發也不能懶,作筆記是一種學習的好習慣!
關注以下公眾號,可獲取兩套視訊教程:【laravel7.x 從入門到核心架構講解】 與 【Laravel高階實戰教程42講】 ,助你提升你的php學習技能。最後祝你學習愉快!
探索下一次技術面試之前應該瞭解的前20個 Laravel 面試問題。
Q1:什麼是Laravel?
Laravel 是一個免費的開放原始碼 PHP Web 框架,由 Taylor Otwell 建立,旨在遵循模型-檢視-控制器(MVC)架構模式開發 Web 應用程式。
Q2: Laravel 與其他 Php 框架相比有哪些好處?
與其他框架相比,設定和自定義過程既簡單又快速。
內建認證系統
支援多個檔案系統
預裝軟體包,例如 Laravel Socialite,Laravel cashier,Laravel elixir,Passport,Laravel Scout
PHP active record 實現的 Eloquent ORM (物件關係對映)
內建命令列工具 “Artisan”,用於建立程式碼框架,資料庫結構並構建其遷移
Q3:解釋 Laravel 中的遷移
Laravel Migrations 類似於資料庫的版本控制,使團隊可以輕鬆地修改和共享應用程式的資料庫架構。遷移通常與 Laravel 的架構生成器搭配使用,以輕鬆構建應用程式的資料庫架構。
Q4:Facade Pattern 有什麼用?
Facades 為應用程式的服務容器中可用的類提供了一個 靜態 介面。Laravel facades 作為服務容器中基礎類的靜態代理,提供了簡潔、表達性強的語法的優勢,同時保持了比傳統靜態方法更高的可測試性和靈活性。
所有的 Laravel facades 都是在 Illuminate\Support\Facades 名稱空間中定義。
檢視:
use Illuminate\Support\Facades\Cache;
Route::get('/cache', function () {
return Cache::get('key');
});
Q5:什麼是服務容器?
Laravel 服務容器 是用於管理類依賴性和執行依賴性注入的工具。
Q6:什麼是 Eloquent Models?
Laravel 附帶的 Eloquent ORM 提供了一個漂亮、簡單的 ActiveRecord 實現,用於處理資料庫。每個資料庫表都有一個對應的模型,用於與該表進行互動。通過模型,您可以查詢表中的資料,以及將新記錄插入表中。
Q7:什麼是Laravel事件?
Laravel 事件提供了一個簡單的觀察者模式實現,允許訂閱和監聽應用程式中的事件。事件是程式檢測並處理的事故或事情。
以下是 Laravel 中的一些事件示例:
新使用者註冊
釋出新評論
使用者登入/登出
新增了新產品。
Q8:你對 Laravel 中的查詢生成器瞭解多少?
Laravel 的資料庫查詢構建器為建立和執行資料庫查詢提供了方便,流暢的介面。它可以用於在應用程式中執行大多數資料庫操作,並且可以在所有支援的資料庫系統上工作。
Laravel 查詢構建器使用 PDO 引數繫結來保護應用程式免受 SQL 注入攻擊。無需清除作為繫結傳遞的字串。
查詢生成器的一些功能:
分塊
聚合
Selects
原生方法
Joins
Unions
Where 語句
Ordering,Grouping,Limit,& Offset
Q9:如何生成遷移?
遷移就像您資料庫的版本控制一樣,使您的團隊可以輕鬆地修改和共享應用程式的資料庫架構。遷移通常與 Laravel 的架構構建器搭配使用,以輕鬆構建應用程式的資料庫架構。
要建立遷移,使用 make:migration Artisan 命令:
php artisan make:migration create_users_table
新的遷移將放置在您的 database/migrations 目錄中。每個遷移檔名都包含一個時間戳,該時間戳使 Laravel 可以確定遷移的順序。
Q10:如何 mock 一個靜態 facade 方法?
Facades 為應用程式的服務容器中可用的類提供“靜態”介面。與傳統的靜態方法呼叫不同,Facades 是可被 mock 的。我們可以使用 shouldReceive 方法 mock 對靜態外觀方法的呼叫,該方法將返回 Mockery mock 的例項。
// 實際程式碼
$value = Cache::get('key');
// 測試
Cache::shouldReceive('get')
->once()
->with('key')
->andReturn('value');
Q11:Eager Loading 有什麼好處,何時使用?
當訪問 Eloquent 關係作為屬性時,關係資料是 “Lazy Loaded” 的。這意味著直到您首次訪問該屬性,關係資料才被實際載入。但是,Eloquent 可以在查詢父模型時 “Eager Load” 關係。
當我們有巢狀物件時(例如書本->作者),Eager Loading 減輕了 N + 1 查詢的問題。我們可以使用 Eager Loading 將此操作減少為僅2個查詢。
Q12:本地作用域有何用?
Scopes 允許您輕鬆地在模型中複用查詢邏輯。要定義 scope,只需在模型方法的前面加上 scope:
class User extends Model {
public function scopePopular($query)
{
return $query->where('votes', '>', 100);
}
public function scopeWomen($query)
{
return $query->whereGender('W');
}
}
用法:
$users = User::popular()->women()->orderBy('created_at')->get();
有時您可能希望定義一個接受引數的 scope。Dynamic scopes 接受查詢引數:
class User extends Model {
public function scopeOfType($query, $type)
{
return $query->whereType($type);
}
}
用法:
$users = User::ofType('member')->get();
Q13:Laravel中的路由命名是什麼?
路由命名使得在生成重定向或者 URL 的時候更加方便地引用路由。您可以通過將 name 方法加到路由定義上來指定命名路由:
Route::get('user/profile', function () {
//
})->name('profile');
您可以為控制器操作指定路由名稱:
Route::get('user/profile', 'UserController@showProfile')->name('profile');
為路由分配名稱後,您可以在生成 URL 或重定向時,通過全域性路由功能使用路由名稱:
// Generating URLs...
$url = route('profile');
// Generating Redirects...
return redirect()->route('profile');
Q14:Laravel中的閉包是什麼?
閉包是一個匿名函式。閉包通常用作回撥方法,並且可以用作函式中的引數
function handle(Closure $closure) {
$closure('Hello World!');
}
handle(function($value){
echo $value;
});
Q15:列出 Laravel 中查詢構建器提供的一些聚合方法?
聚合函式是一種功能,能夠將多行的值組合在一起,作為某些條件下的輸入,以形成具有更重要含義或度量值(例如集合,包或列表)的單個值。
以下是 Laravel 查詢構建器提供的一些聚合方法的列表:
count()
$products = DB::table(‘products’)->count();
max()
$price = DB::table(‘orders’)->max(‘price’);
min()
$price = DB::table(‘orders’)->min(‘price’);
avg()
*$price = DB::table(‘orders’)->avg(‘price’);
sum()
$price = DB::table(‘orders’)->sum(‘price’);
Q16:什麼是 Laravel 中的反向路由?
在 Laravel 中,反向路由會根據路由宣告生成 URL。反向路由使您的應用程式更加靈活。例如,下面的路由宣告告訴 Laravel 當請求的 URI 為 “login” 時在 users 控制器中執行 “login” 操作。
mysite.com/login
Route::get(‘login’, ‘users@login’);
使用反向路由,我們可以建立到它的連結並傳遞我們定義的任何引數。如果未提供可選引數,則會從生成的連結中刪除。
{{ HTML::link_to_action('users@login') }}
它將在檢視中建立類似 mysite.com/login 的連結。
Q17: :讓我們為 PHP 建立列舉,提供一些程式碼示例。
如果我們的程式碼需要對列舉常量和值進行更多驗證,該怎麼辦?
根據使用情況,我通常會使用類似以下的簡單內容:
abstract class DaysOfWeek
{
const Sunday = 0;
const Monday = 1;
// etc.
}
$today = DaysOfWeek::Sunday;
這是一個擴充套件的示例,可以更好地服務於更廣泛的案例:
abstract class BasicEnum {
private static $constCacheArray = NULL;
private static function getConstants() {
if (self::$constCacheArray == NULL) {
self::$constCacheArray = [];
}
$calledClass = get_called_class();
if (!array_key_exists($calledClass, self::$constCacheArray)) {
$reflect = new ReflectionClass($calledClass);
self::$constCacheArray[$calledClass] = $reflect - > getConstants();
}
return self::$constCacheArray[$calledClass];
}
public static function isValidName($name, $strict = false) {
$constants = self::getConstants();
if ($strict) {
return array_key_exists($name, $constants);
}
$keys = array_map('strtolower', array_keys($constants));
return in_array(strtolower($name), $keys);
}
public static function isValidValue($value, $strict = true) {
$values = array_values(self::getConstants());
return in_array($value, $values, $strict);
}
}
我們可以將其用作:
abstract class DaysOfWeek extends BasicEnum {
const Sunday = 0;
const Monday = 1;
const Tuesday = 2;
const Wednesday = 3;
const Thursday = 4;
const Friday = 5;
const Saturday = 6;
}
DaysOfWeek::isValidName('Humpday'); // false
DaysOfWeek::isValidName('Monday'); // true
DaysOfWeek::isValidName('monday'); // true
DaysOfWeek::isValidName('monday', $strict = true); // false
DaysOfWeek::isValidName(0); // false
DaysOfWeek::isValidValue(0); // true
DaysOfWeek::isValidValue(5); // true
DaysOfWeek::isValidValue(7); // false
DaysOfWeek::isValidValue('Friday'); // false
Q18:什麼是PHP自動載入類?
使用自動載入器,PHP 允許在由於錯誤而失敗之前最後一次載入類或介面。
PHP中的 spl_autoload_register()函式可以註冊任意數量的自動載入器,即使未定義類和介面也可以自動載入。
spl_autoload_register(function ($classname) {
include $classname . '.php';
});
$object = new Class1();
$object2 = new Class2();
在上面的示例中,我們不需要包含 Class1.php 和 Class2.php。spl_autoload_register() 函式將自動載入 Class1.php 和 Class2.php。
Q19:PHP是否支援方法過載?
方法過載是使用具有不同簽名的相同方法名稱的現象。PHP 中函式簽名僅基於它們的名稱,並且不包含引數列表,因此不能有兩個具有相同名稱的函式,所以 PHP 不支援方法過載。
但是,您可以宣告一個可變函式,它接受可變數量的引數。您可以使用 func_num_args() 和 func_get_arg() 來傳遞引數並正常使用它們。
function myFunc() {
for ($i = 0; $i < func_num_args(); $i++) {
printf("Argument %d: %s\n", $i, func_get_arg($i));
}
}
/*
Argument 0: a
Argument 1: 2
Argument 2: 3.5
*/
myFunc('a', 2, 3.5);
Q20:Laravel 中為什麼需要 Traits?
Traits 已被新增到 PHP 中,原因很簡單s:PHP 不支援多重繼承。簡而言之,一個類不能一次性擴充套件至多個類。當你需要在其他類也使用的兩個不同類中宣告的功能時,這變得很費力,結果是你必須重複執行程式碼才能完成工作,而不會糾纏自己。
引入 Traits,它能使我們宣告一種包含多個可複用方法的類。更好的是,它們的方法可以直接注入到你使用的任何類中,並且你可以在同一類中使用多個 Trait。讓我們看一個簡單的 Hello World 示例。
trait SayHello
{
private function hello()
{
return "Hello ";
}
private function world()
{
return "World";
}
}
trait Talk
{
private function speak()
{
echo $this->hello() . $this->world();
}
}
class HelloWorld
{
use SayHello;
use Talk;
public function __construct()
{
$this->speak();
}
}
$message = new HelloWorld(); // returns "Hello World";
Q21:PHP 中的 Autoloader 是什麼?
自動載入器定義了自動在程式碼中包含 PHP 類的方法,而不必使用諸如 require 和 include 之類的語句。
PSR-4 將支援更簡單的資料夾結構,但是將使我們僅通過檢視完全限定的名稱就無法知道類的確切路徑。
PSR-0 在硬碟驅動器上比較混亂,但是支援念舊的開發人員(類名下劃線使用者),並幫助我們通過以下方式辨別類的位置:看它的名字。
Q22:在 PHP 中 yield 是什麼意思?
解釋此程式碼以及 yield 的作用:
function a($items) {
foreach ($items as $item) {
yield $item + 1;
}
}
yield 關鍵字從生成器函式返回資料。生成器函式實際上是編寫 Iterator 的更緊湊和有效的方式。它允許您定義一個函式,該函式將在您遍歷該函式時計算並返回值。
因此,問題中的函式與以下內容的函式幾乎相同:
function b($items) {
$result = [];
foreach ($items as $item) {
$result[] = $item + 1;
}
return $result;
}
只有一個區別,a() 返回一個 generator,而 b() 只是一個簡單的 陣列。而且兩者都可以被迭代。
函式的生成器版本未分配完整的陣列,因此對記憶體的需求較少。生成器可用於解決記憶體限制。由於生成器僅按需計算其 yielded 值,因此它們用於代替計算成本昂貴或無法一次性計算的序列很有用。
Q23:$$$ 在 PHP 中是什麼意思?
類似 $$variable 的語法稱為可變變數。
讓我們嘗試 $$$:
$real_variable = 'test';
$name = 'real_variable'; // variable variable for real variable
$name_of_name = 'name'; // variable variable for variable variable
echo $name_of_name . '<br />';
echo $$name_of_name . '<br />';
echo $$$name_of_name . '<br />';
這是輸出:
name
real_variable
test
本作品採用《CC 協議》,轉載必須註明作者和本文連結