[{"data":1,"prerenderedAt":46952},["ShallowReactive",2],{"/post/php-syntax-recap":3,"related-/backend/php-syntax-recap":10981},{"id":4,"title":5,"author":6,"body":7,"date":10964,"description":10965,"draft":10966,"extension":10967,"guide":10968,"image":10969,"meta":10970,"navigation":109,"path":10971,"seo":10972,"stem":10973,"tags":10974,"__hash__":10980},"blog/Backend/8.php-syntax-recap.md","PHP Syntax Recap: Learn PHP Fast","Kashyap Kumar",{"type":8,"value":9,"toc":10890},"minimark",[10,19,38,43,82,230,237,241,246,257,361,365,416,512,516,555,804,808,839,962,966,1000,1141,1152,1156,1160,1196,1335,1339,1379,1486,1490,1532,1626,1630,1664,1786,1790,1832,1951,1973,1977,1981,2006,2206,2210,2221,2283,2287,2301,2790,2794,2801,2871,2895,2899,2903,2925,3105,3112,3116,3140,3313,3317,3349,3575,3579,3595,4049,4053,4067,4205,4381,4385,4403,4562,4576,4580,4584,4629,4876,4880,4897,5109,5122,5126,5130,5150,5326,5330,5344,5484,5488,5500,5599,5603,5625,5826,5830,5849,5919,5923,5933,6082,6090,6094,6101,6113,6318,6322,6343,6463,6467,6483,6680,6684,6691,6807,6811,6831,6991,6995,7010,7182,7186,7193,7410,7414,7425,7640,7651,7655,7666,7900,7904,7931,8182,8186,8223,8463,8467,8487,8613,8617,8644,8748,8752,8756,8774,8926,8930,8949,9021,9025,9079,9085,9089,9109,9273,9289,9293,9297,9322,9417,9421,9444,9670,9674,9706,9815,9819,9838,9972,9976,10008,10174,10178,10204,10477,10480,10484,10487,10518,10575,10602,10611,10617,10641,10668,10704,10729,10759,10775,10796,10841,10873,10886],[11,12,13,14,18],"p",{},"If you already know how to program and have written PHP before, you do not need a tutorial; you need the specific shapes PHP gives to ideas you already understand, plus the behaviors that differ from Java, Python, or JavaScript and quietly cost you points under interview pressure. Modern PHP (8.0 and up) is also a very different language from the one most people half-remember: it has real type declarations, enums, ",[15,16,17],"code",{},"match",", named arguments, and a null-safe operator, and an interviewer will notice if you write it like it is 2014.",[11,20,21,22,27,28,32,33,37],{},"This recap is deliberately thorough rather than minimal, because \"I forgot that function existed\" is exactly what trips people up in a live round. It is organized by theme so you can skim to what you have gone rusty on, every concept comes with runnable code, and the constructs that people tend to only half-remember (constructor promotion, abstract classes, traits, generators) get a real explanation rather than a one-liner. If you are using this to prepare for a PHP backend role, pair it with the ",[23,24,26],"a",{"href":25},"/post/top-111-laravel-interview-questions","Top 111 Laravel Interview Questions"," for the framework layer and the ",[23,29,31],{"href":30},"/post/top-111-backend-interview-questions","Top 111 Backend Interview Questions"," for the framework-agnostic side (HTTP, databases, and system design). If you also work in Go, the ",[23,34,36],{"href":35},"/post/go-syntax-recap","Go Syntax Recap"," is the sibling article in this series.",[39,40,42],"h2",{"id":41},"how-to-read-and-run-php","How to Read and Run PHP",[11,44,45,46,49,50,53,54,57,58,61,62,65,66,69,70,73,74,77,78,81],{},"PHP code lives inside ",[15,47,48],{},"\u003C?php ?>"," tags because the language was built to be embedded in HTML, but a modern ",[15,51,52],{},".php"," file that contains only code opens with ",[15,55,56],{},"\u003C?php"," and omits the closing tag entirely, which avoids accidentally emitting trailing whitespace. Every statement ends with a semicolon, and you print with ",[15,59,60],{},"echo"," (which takes one or more values) or ",[15,63,64],{},"print"," (which takes one and returns ",[15,67,68],{},"1","). You run a script with ",[15,71,72],{},"php file.php",", evaluate a snippet with ",[15,75,76],{},"php -r 'code'",", or open an interactive shell with ",[15,79,80],{},"php -a",".",[83,84,89],"pre",{"className":85,"code":86,"language":87,"meta":88,"style":88},"language-php shiki shiki-themes github-dark","\u003C?php\n\ndeclare(strict_types=1);   // opt into strict type checking; must be the first statement\n\n// This is a single-line comment.\n# So is this.\n/* And this is a block comment. */\n\necho \"Hello, world\\n\";          // echo prints; \\n works inside double quotes\necho 'a', 'b', 'c', PHP_EOL;    // echo accepts multiple arguments; PHP_EOL is the newline\nprint \"print returns 1\\n\";\n","php","",[15,90,91,104,111,136,141,147,153,159,164,185,215],{"__ignoreMap":88},[92,93,96,100],"span",{"class":94,"line":95},"line",1,[92,97,99],{"class":98},"snl16","\u003C?",[92,101,103],{"class":102},"sDLfK","php\n",[92,105,107],{"class":94,"line":106},2,[92,108,110],{"emptyLinePlaceholder":109},true,"\n",[92,112,114,117,121,124,127,129,132],{"class":94,"line":113},3,[92,115,116],{"class":98},"declare",[92,118,120],{"class":119},"s95oV","(",[92,122,123],{"class":102},"strict_types",[92,125,126],{"class":98},"=",[92,128,68],{"class":102},[92,130,131],{"class":119},");   ",[92,133,135],{"class":134},"sAwPA","// opt into strict type checking; must be the first statement\n",[92,137,139],{"class":94,"line":138},4,[92,140,110],{"emptyLinePlaceholder":109},[92,142,144],{"class":94,"line":143},5,[92,145,146],{"class":134},"// This is a single-line comment.\n",[92,148,150],{"class":94,"line":149},6,[92,151,152],{"class":134},"# So is this.\n",[92,154,156],{"class":94,"line":155},7,[92,157,158],{"class":134},"/* And this is a block comment. */\n",[92,160,162],{"class":94,"line":161},8,[92,163,110],{"emptyLinePlaceholder":109},[92,165,167,169,173,176,179,182],{"class":94,"line":166},9,[92,168,60],{"class":102},[92,170,172],{"class":171},"sU2Wk"," \"Hello, world",[92,174,175],{"class":102},"\\n",[92,177,178],{"class":171},"\"",[92,180,181],{"class":119},";          ",[92,183,184],{"class":134},"// echo prints; \\n works inside double quotes\n",[92,186,188,190,193,196,199,201,204,206,209,212],{"class":94,"line":187},10,[92,189,60],{"class":102},[92,191,192],{"class":171}," 'a'",[92,194,195],{"class":119},", ",[92,197,198],{"class":171},"'b'",[92,200,195],{"class":119},[92,202,203],{"class":171},"'c'",[92,205,195],{"class":119},[92,207,208],{"class":102},"PHP_EOL",[92,210,211],{"class":119},";    ",[92,213,214],{"class":134},"// echo accepts multiple arguments; PHP_EOL is the newline\n",[92,216,218,220,223,225,227],{"class":94,"line":217},11,[92,219,64],{"class":102},[92,221,222],{"class":171}," \"print returns 1",[92,224,175],{"class":102},[92,226,178],{"class":171},[92,228,229],{"class":119},";\n",[11,231,232,233,81],{},"That runs PHP on your own machine. When you are ready to run it in production without managing a server, walk through ",[23,234,236],{"href":235},"/post/deploy-laravel-on-aws-lambda-with-bref","how to deploy a Laravel app on AWS Lambda with Bref",[39,238,240],{"id":239},"variables-and-types","Variables and Types",[242,243,245],"h3",{"id":244},"declaring-variables","Declaring variables",[11,247,248,249,252,253,256],{},"Every variable name starts with ",[15,250,251],{},"$",", needs no declaration keyword, and holds whatever type you last assigned; the type belongs to the value, not the name. Variable names are case-sensitive, and the convention is ",[15,254,255],{},"$camelCase",". There is no block scoping: a variable exists from its first assignment to the end of the function (or the end of the script at the top level).",[83,258,260],{"className":85,"code":259,"language":87,"meta":88,"style":88},"$name   = 'Ada';\n$count  = 42;\n$active = true;\n$count  = 'now a string';   // legal; the variable simply rebinds to a new type\n\n$a = $b = 0;                // chained assignment: both become 0\n[$x, $y] = [1, 2];          // destructuring: $x is 1, $y is 2\n",[15,261,262,274,286,298,313,317,338],{"__ignoreMap":88},[92,263,264,267,269,272],{"class":94,"line":95},[92,265,266],{"class":119},"$name   ",[92,268,126],{"class":98},[92,270,271],{"class":171}," 'Ada'",[92,273,229],{"class":119},[92,275,276,279,281,284],{"class":94,"line":106},[92,277,278],{"class":119},"$count  ",[92,280,126],{"class":98},[92,282,283],{"class":102}," 42",[92,285,229],{"class":119},[92,287,288,291,293,296],{"class":94,"line":113},[92,289,290],{"class":119},"$active ",[92,292,126],{"class":98},[92,294,295],{"class":102}," true",[92,297,229],{"class":119},[92,299,300,302,304,307,310],{"class":94,"line":138},[92,301,278],{"class":119},[92,303,126],{"class":98},[92,305,306],{"class":171}," 'now a string'",[92,308,309],{"class":119},";   ",[92,311,312],{"class":134},"// legal; the variable simply rebinds to a new type\n",[92,314,315],{"class":94,"line":143},[92,316,110],{"emptyLinePlaceholder":109},[92,318,319,322,324,327,329,332,335],{"class":94,"line":149},[92,320,321],{"class":119},"$a ",[92,323,126],{"class":98},[92,325,326],{"class":119}," $b ",[92,328,126],{"class":98},[92,330,331],{"class":102}," 0",[92,333,334],{"class":119},";                ",[92,336,337],{"class":134},"// chained assignment: both become 0\n",[92,339,340,343,345,348,350,352,355,358],{"class":94,"line":155},[92,341,342],{"class":119},"[$x, $y] ",[92,344,126],{"class":98},[92,346,347],{"class":119}," [",[92,349,68],{"class":102},[92,351,195],{"class":119},[92,353,354],{"class":102},"2",[92,356,357],{"class":119},"];          ",[92,359,360],{"class":134},"// destructuring: $x is 1, $y is 2\n",[242,362,364],{"id":363},"the-type-system","The type system",[11,366,367,368,195,371,195,374,195,377,380,381,195,384,387,388,195,391,394,395,398,399,401,402,404,405,408,409,412,413,415],{},"PHP has four scalar types (",[15,369,370],{},"int",[15,372,373],{},"float",[15,375,376],{},"string",[15,378,379],{},"bool","), two compound types (",[15,382,383],{},"array",[15,385,386],{},"object","), plus ",[15,389,390],{},"null",[15,392,393],{},"callable",", and ",[15,396,397],{},"iterable",". There is no separate character type, ",[15,400,370],{}," is 64-bit on modern platforms, and ",[15,403,373],{}," is a IEEE 754 double. The one naming trap is that ",[15,406,407],{},"gettype()"," reports a float as ",[15,410,411],{},"\"double\"",", a historical quirk you should recognize even though you will rarely call ",[15,414,407],{}," in real code.",[83,417,419],{"className":85,"code":418,"language":87,"meta":88,"style":88},"gettype(42);        // \"integer\"\ngettype(3.14);      // \"double\"  (not \"float\"; a legacy name)\ngettype('hi');      // \"string\"\ngettype(true);      // \"boolean\"\ngettype([1, 2]);    // \"array\"\ngettype(null);      // \"NULL\"\n",[15,420,421,437,452,466,480,499],{"__ignoreMap":88},[92,422,423,426,428,431,434],{"class":94,"line":95},[92,424,425],{"class":102},"gettype",[92,427,120],{"class":119},[92,429,430],{"class":102},"42",[92,432,433],{"class":119},");        ",[92,435,436],{"class":134},"// \"integer\"\n",[92,438,439,441,443,446,449],{"class":94,"line":106},[92,440,425],{"class":102},[92,442,120],{"class":119},[92,444,445],{"class":102},"3.14",[92,447,448],{"class":119},");      ",[92,450,451],{"class":134},"// \"double\"  (not \"float\"; a legacy name)\n",[92,453,454,456,458,461,463],{"class":94,"line":113},[92,455,425],{"class":102},[92,457,120],{"class":119},[92,459,460],{"class":171},"'hi'",[92,462,448],{"class":119},[92,464,465],{"class":134},"// \"string\"\n",[92,467,468,470,472,475,477],{"class":94,"line":138},[92,469,425],{"class":102},[92,471,120],{"class":119},[92,473,474],{"class":102},"true",[92,476,448],{"class":119},[92,478,479],{"class":134},"// \"boolean\"\n",[92,481,482,484,487,489,491,493,496],{"class":94,"line":143},[92,483,425],{"class":102},[92,485,486],{"class":119},"([",[92,488,68],{"class":102},[92,490,195],{"class":119},[92,492,354],{"class":102},[92,494,495],{"class":119},"]);    ",[92,497,498],{"class":134},"// \"array\"\n",[92,500,501,503,505,507,509],{"class":94,"line":149},[92,502,425],{"class":102},[92,504,120],{"class":119},[92,506,390],{"class":102},[92,508,448],{"class":119},[92,510,511],{"class":134},"// \"NULL\"\n",[242,513,515],{"id":514},"checking-and-casting-types","Checking and casting types",[11,517,518,519,521,522,525,526,529,530,529,533,529,536,539,540,543,544,547,548,551,552,81],{},"Instead of ",[15,520,407],{},", test a type with the ",[15,523,524],{},"is_*"," family, which returns a clean boolean and reads well in conditions. To convert between types, put the target type in parentheses before the value (a \"cast\"), or use the ",[15,527,528],{},"intval","/",[15,531,532],{},"floatval",[15,534,535],{},"strval",[15,537,538],{},"boolval"," functions when you want a callable you can pass around. Casting follows PHP's coercion rules, so ",[15,541,542],{},"(int) \"12abc\""," reads the leading digits and gives ",[15,545,546],{},"12",", while ",[15,549,550],{},"(int) \"abc\""," gives ",[15,553,554],{},"0",[83,556,558],{"className":85,"code":557,"language":87,"meta":88,"style":88},"is_int(42);          // true\nis_float(3.14);      // true\nis_string('hi');     // true\nis_bool(true);       // true\nis_array([1]);       // true\nis_null($x);         // true if $x is null\nis_numeric('1.5e3'); // true: a numeric string counts\nis_callable('strlen'); // true\n\n(int) '12abc';       // 12  (reads leading digits)\n(int) '3.9';         // 3   (truncates, does not round)\n(float) '2.5kg';     // 2.5\n(bool) '0';          // false  (see the falsy-values gotcha)\n(string) true;       // '1';  (string) false is '' (empty)\n(array) 'x';         // ['x']  (wraps a scalar in a one-element array)\n\nintval('0x1A', 16);  // 26  (parse as base 16)\n",[15,559,560,575,588,602,616,630,641,657,671,675,693,710,728,745,761,778,783],{"__ignoreMap":88},[92,561,562,565,567,569,572],{"class":94,"line":95},[92,563,564],{"class":102},"is_int",[92,566,120],{"class":119},[92,568,430],{"class":102},[92,570,571],{"class":119},");          ",[92,573,574],{"class":134},"// true\n",[92,576,577,580,582,584,586],{"class":94,"line":106},[92,578,579],{"class":102},"is_float",[92,581,120],{"class":119},[92,583,445],{"class":102},[92,585,448],{"class":119},[92,587,574],{"class":134},[92,589,590,593,595,597,600],{"class":94,"line":113},[92,591,592],{"class":102},"is_string",[92,594,120],{"class":119},[92,596,460],{"class":171},[92,598,599],{"class":119},");     ",[92,601,574],{"class":134},[92,603,604,607,609,611,614],{"class":94,"line":138},[92,605,606],{"class":102},"is_bool",[92,608,120],{"class":119},[92,610,474],{"class":102},[92,612,613],{"class":119},");       ",[92,615,574],{"class":134},[92,617,618,621,623,625,628],{"class":94,"line":143},[92,619,620],{"class":102},"is_array",[92,622,486],{"class":119},[92,624,68],{"class":102},[92,626,627],{"class":119},"]);       ",[92,629,574],{"class":134},[92,631,632,635,638],{"class":94,"line":149},[92,633,634],{"class":102},"is_null",[92,636,637],{"class":119},"($x);         ",[92,639,640],{"class":134},"// true if $x is null\n",[92,642,643,646,648,651,654],{"class":94,"line":155},[92,644,645],{"class":102},"is_numeric",[92,647,120],{"class":119},[92,649,650],{"class":171},"'1.5e3'",[92,652,653],{"class":119},"); ",[92,655,656],{"class":134},"// true: a numeric string counts\n",[92,658,659,662,664,667,669],{"class":94,"line":161},[92,660,661],{"class":102},"is_callable",[92,663,120],{"class":119},[92,665,666],{"class":171},"'strlen'",[92,668,653],{"class":119},[92,670,574],{"class":134},[92,672,673],{"class":94,"line":166},[92,674,110],{"emptyLinePlaceholder":109},[92,676,677,679,681,684,687,690],{"class":94,"line":187},[92,678,120],{"class":119},[92,680,370],{"class":98},[92,682,683],{"class":119},") ",[92,685,686],{"class":171},"'12abc'",[92,688,689],{"class":119},";       ",[92,691,692],{"class":134},"// 12  (reads leading digits)\n",[92,694,695,697,699,701,704,707],{"class":94,"line":217},[92,696,120],{"class":119},[92,698,370],{"class":98},[92,700,683],{"class":119},[92,702,703],{"class":171},"'3.9'",[92,705,706],{"class":119},";         ",[92,708,709],{"class":134},"// 3   (truncates, does not round)\n",[92,711,713,715,717,719,722,725],{"class":94,"line":712},12,[92,714,120],{"class":119},[92,716,373],{"class":98},[92,718,683],{"class":119},[92,720,721],{"class":171},"'2.5kg'",[92,723,724],{"class":119},";     ",[92,726,727],{"class":134},"// 2.5\n",[92,729,731,733,735,737,740,742],{"class":94,"line":730},13,[92,732,120],{"class":119},[92,734,379],{"class":98},[92,736,683],{"class":119},[92,738,739],{"class":171},"'0'",[92,741,181],{"class":119},[92,743,744],{"class":134},"// false  (see the falsy-values gotcha)\n",[92,746,748,750,752,754,756,758],{"class":94,"line":747},14,[92,749,120],{"class":119},[92,751,376],{"class":98},[92,753,683],{"class":119},[92,755,474],{"class":102},[92,757,689],{"class":119},[92,759,760],{"class":134},"// '1';  (string) false is '' (empty)\n",[92,762,764,766,768,770,773,775],{"class":94,"line":763},15,[92,765,120],{"class":119},[92,767,383],{"class":98},[92,769,683],{"class":119},[92,771,772],{"class":171},"'x'",[92,774,706],{"class":119},[92,776,777],{"class":134},"// ['x']  (wraps a scalar in a one-element array)\n",[92,779,781],{"class":94,"line":780},16,[92,782,110],{"emptyLinePlaceholder":109},[92,784,786,788,790,793,795,798,801],{"class":94,"line":785},17,[92,787,528],{"class":102},[92,789,120],{"class":119},[92,791,792],{"class":171},"'0x1A'",[92,794,195],{"class":119},[92,796,797],{"class":102},"16",[92,799,800],{"class":119},");  ",[92,802,803],{"class":134},"// 26  (parse as base 16)\n",[242,805,807],{"id":806},"constants-and-predefined-values","Constants and predefined values",[11,809,810,811,813,814,817,818,821,822,195,825,394,827,830,831,834,835,838],{},"A constant is a name bound to a value that cannot change after definition, and unlike variables it carries no ",[15,812,251],{},". Use the ",[15,815,816],{},"const"," keyword for compile-time constants (including inside classes) and the ",[15,819,820],{},"define()"," function when you need to compute the name or value at runtime. PHP also ships useful predefined constants such as ",[15,823,824],{},"PHP_INT_MAX",[15,826,208],{},[15,828,829],{},"M_PI",", plus \"magic constants\" like ",[15,832,833],{},"__LINE__"," and ",[15,836,837],{},"__DIR__"," that resolve to where they appear in the source.",[83,840,842],{"className":85,"code":841,"language":87,"meta":88,"style":88},"const MAX_RETRIES = 3;          // preferred for a fixed value\ndefine('APP_ENV', 'prod');      // runtime definition\necho defined('APP_ENV') ? 'yes' : 'no';\n\necho PHP_INT_MAX;   // 9223372036854775807 on 64-bit\necho PHP_EOL;       // \"\\n\" on Unix, \"\\r\\n\" on Windows\necho __LINE__;      // the current line number\necho __DIR__;       // the directory of the current file\n",[15,843,844,862,882,909,913,925,937,950],{"__ignoreMap":88},[92,845,846,848,851,854,857,859],{"class":94,"line":95},[92,847,816],{"class":98},[92,849,850],{"class":102}," MAX_RETRIES",[92,852,853],{"class":98}," =",[92,855,856],{"class":102}," 3",[92,858,181],{"class":119},[92,860,861],{"class":134},"// preferred for a fixed value\n",[92,863,864,867,869,872,874,877,879],{"class":94,"line":106},[92,865,866],{"class":102},"define",[92,868,120],{"class":119},[92,870,871],{"class":171},"'APP_ENV'",[92,873,195],{"class":119},[92,875,876],{"class":171},"'prod'",[92,878,448],{"class":119},[92,880,881],{"class":134},"// runtime definition\n",[92,883,884,886,889,891,893,895,898,901,904,907],{"class":94,"line":113},[92,885,60],{"class":102},[92,887,888],{"class":102}," defined",[92,890,120],{"class":119},[92,892,871],{"class":171},[92,894,683],{"class":119},[92,896,897],{"class":98},"?",[92,899,900],{"class":171}," 'yes'",[92,902,903],{"class":98}," :",[92,905,906],{"class":171}," 'no'",[92,908,229],{"class":119},[92,910,911],{"class":94,"line":138},[92,912,110],{"emptyLinePlaceholder":109},[92,914,915,917,920,922],{"class":94,"line":143},[92,916,60],{"class":102},[92,918,919],{"class":102}," PHP_INT_MAX",[92,921,309],{"class":119},[92,923,924],{"class":134},"// 9223372036854775807 on 64-bit\n",[92,926,927,929,932,934],{"class":94,"line":149},[92,928,60],{"class":102},[92,930,931],{"class":102}," PHP_EOL",[92,933,689],{"class":119},[92,935,936],{"class":134},"// \"\\n\" on Unix, \"\\r\\n\" on Windows\n",[92,938,939,941,944,947],{"class":94,"line":155},[92,940,60],{"class":102},[92,942,943],{"class":102}," __LINE__",[92,945,946],{"class":119},";      ",[92,948,949],{"class":134},"// the current line number\n",[92,951,952,954,957,959],{"class":94,"line":161},[92,953,60],{"class":102},[92,955,956],{"class":102}," __DIR__",[92,958,689],{"class":119},[92,960,961],{"class":134},"// the directory of the current file\n",[242,963,965],{"id":964},"isset-empty-and-unset","isset, empty, and unset",[11,967,968,969,972,973,975,976,979,980,983,984,987,988,990,991,993,994,997,998,81],{},"Because a variable or array key can be missing entirely, PHP gives you three language constructs to probe existence. ",[15,970,971],{},"isset()"," is true when a variable is set and not ",[15,974,390],{},"; ",[15,977,978],{},"empty()"," is true when a variable is missing or holds any falsy value; and ",[15,981,982],{},"unset()"," destroys a variable or removes an array element. The subtle part is that ",[15,985,986],{},"empty(\"0\")"," is ",[15,989,474],{},", so use ",[15,992,978],{}," only when you genuinely mean \"missing or falsy,\" and reach for ",[15,995,996],{},"array_key_exists()"," when a key might legitimately hold ",[15,999,390],{},[83,1001,1003],{"className":85,"code":1002,"language":87,"meta":88,"style":88},"$user = ['name' => 'Ada', 'nickname' => null];\n\nisset($user['name']);              // true\nisset($user['nickname']);          // false: the value is null\nisset($user['missing']);           // false\narray_key_exists('nickname', $user); // true: the key exists, value is null\nempty($user['name']);              // false\nempty($user['missing']);           // true\n\nunset($user['name']);              // removes the key\n",[15,1004,1005,1035,1039,1054,1068,1083,1098,1111,1123,1127],{"__ignoreMap":88},[92,1006,1007,1010,1012,1014,1017,1020,1022,1024,1027,1029,1032],{"class":94,"line":95},[92,1008,1009],{"class":119},"$user ",[92,1011,126],{"class":98},[92,1013,347],{"class":119},[92,1015,1016],{"class":171},"'name'",[92,1018,1019],{"class":98}," =>",[92,1021,271],{"class":171},[92,1023,195],{"class":119},[92,1025,1026],{"class":171},"'nickname'",[92,1028,1019],{"class":98},[92,1030,1031],{"class":102}," null",[92,1033,1034],{"class":119},"];\n",[92,1036,1037],{"class":94,"line":106},[92,1038,110],{"emptyLinePlaceholder":109},[92,1040,1041,1044,1047,1049,1052],{"class":94,"line":113},[92,1042,1043],{"class":102},"isset",[92,1045,1046],{"class":119},"($user[",[92,1048,1016],{"class":171},[92,1050,1051],{"class":119},"]);              ",[92,1053,574],{"class":134},[92,1055,1056,1058,1060,1062,1065],{"class":94,"line":138},[92,1057,1043],{"class":102},[92,1059,1046],{"class":119},[92,1061,1026],{"class":171},[92,1063,1064],{"class":119},"]);          ",[92,1066,1067],{"class":134},"// false: the value is null\n",[92,1069,1070,1072,1074,1077,1080],{"class":94,"line":143},[92,1071,1043],{"class":102},[92,1073,1046],{"class":119},[92,1075,1076],{"class":171},"'missing'",[92,1078,1079],{"class":119},"]);           ",[92,1081,1082],{"class":134},"// false\n",[92,1084,1085,1088,1090,1092,1095],{"class":94,"line":149},[92,1086,1087],{"class":102},"array_key_exists",[92,1089,120],{"class":119},[92,1091,1026],{"class":171},[92,1093,1094],{"class":119},", $user); ",[92,1096,1097],{"class":134},"// true: the key exists, value is null\n",[92,1099,1100,1103,1105,1107,1109],{"class":94,"line":155},[92,1101,1102],{"class":102},"empty",[92,1104,1046],{"class":119},[92,1106,1016],{"class":171},[92,1108,1051],{"class":119},[92,1110,1082],{"class":134},[92,1112,1113,1115,1117,1119,1121],{"class":94,"line":161},[92,1114,1102],{"class":102},[92,1116,1046],{"class":119},[92,1118,1076],{"class":171},[92,1120,1079],{"class":119},[92,1122,574],{"class":134},[92,1124,1125],{"class":94,"line":166},[92,1126,110],{"emptyLinePlaceholder":109},[92,1128,1129,1132,1134,1136,1138],{"class":94,"line":187},[92,1130,1131],{"class":102},"unset",[92,1133,1046],{"class":119},[92,1135,1016],{"class":171},[92,1137,1051],{"class":119},[92,1139,1140],{"class":134},"// removes the key\n",[11,1142,1143,1144,1147,1148,1151],{},"The type system rarely drives the problem in a coding round, but adding ",[15,1145,1146],{},"declare(strict_types=1)"," at the top of the file turns silent coercion into a loud ",[15,1149,1150],{},"TypeError",", which surfaces the class of bug where a stray string slides into an integer parameter and hides a logic error until much later.",[39,1153,1155],{"id":1154},"operators","Operators",[242,1157,1159],{"id":1158},"arithmetic-and-assignment","Arithmetic and assignment",[11,1161,1162,1163,1166,1167,1169,1170,1172,1173,834,1176,1179,1180,195,1183,195,1186,1189,1190,1192,1193,81],{},"The arithmetic operators are conventional, with two things worth flagging: ",[15,1164,1165],{},"**"," is exponentiation and is right-associative, and ",[15,1168,529],{}," returns a ",[15,1171,373],{}," unless both operands are integers that divide evenly, so use ",[15,1174,1175],{},"intdiv()",[15,1177,1178],{},"%"," when you want strict integer math. Every arithmetic operator has a compound-assignment form (",[15,1181,1182],{},"+=",[15,1184,1185],{},"-=",[15,1187,1188],{},"*=",", and so on), and string concatenation has its own operator, ",[15,1191,81],{},", with the matching ",[15,1194,1195],{},".=",[83,1197,1199],{"className":85,"code":1198,"language":87,"meta":88,"style":88},"7 + 3;      // 10\n7 / 2;      // 3.5  (float, because 7 and 2 do not divide evenly)\n6 / 2;      // 3    (int, because they divide evenly)\nintdiv(7, 2); // 3  (forced integer division)\n7 % 3;      // 1    (modulo; operands are cast to int)\n2 ** 10;    // 1024 (exponentiation)\n\n$total = 10;\n$total += 5;   // 15\n$total .= '!'; // '15!'  (.= concatenates onto a string)\n",[15,1200,1201,1216,1231,1245,1263,1277,1292,1296,1307,1321],{"__ignoreMap":88},[92,1202,1203,1206,1209,1211,1213],{"class":94,"line":95},[92,1204,1205],{"class":102},"7",[92,1207,1208],{"class":98}," +",[92,1210,856],{"class":102},[92,1212,946],{"class":119},[92,1214,1215],{"class":134},"// 10\n",[92,1217,1218,1220,1223,1226,1228],{"class":94,"line":106},[92,1219,1205],{"class":102},[92,1221,1222],{"class":98}," /",[92,1224,1225],{"class":102}," 2",[92,1227,946],{"class":119},[92,1229,1230],{"class":134},"// 3.5  (float, because 7 and 2 do not divide evenly)\n",[92,1232,1233,1236,1238,1240,1242],{"class":94,"line":113},[92,1234,1235],{"class":102},"6",[92,1237,1222],{"class":98},[92,1239,1225],{"class":102},[92,1241,946],{"class":119},[92,1243,1244],{"class":134},"// 3    (int, because they divide evenly)\n",[92,1246,1247,1250,1252,1254,1256,1258,1260],{"class":94,"line":138},[92,1248,1249],{"class":102},"intdiv",[92,1251,120],{"class":119},[92,1253,1205],{"class":102},[92,1255,195],{"class":119},[92,1257,354],{"class":102},[92,1259,653],{"class":119},[92,1261,1262],{"class":134},"// 3  (forced integer division)\n",[92,1264,1265,1267,1270,1272,1274],{"class":94,"line":143},[92,1266,1205],{"class":102},[92,1268,1269],{"class":98}," %",[92,1271,856],{"class":102},[92,1273,946],{"class":119},[92,1275,1276],{"class":134},"// 1    (modulo; operands are cast to int)\n",[92,1278,1279,1281,1284,1287,1289],{"class":94,"line":149},[92,1280,354],{"class":102},[92,1282,1283],{"class":98}," **",[92,1285,1286],{"class":102}," 10",[92,1288,211],{"class":119},[92,1290,1291],{"class":134},"// 1024 (exponentiation)\n",[92,1293,1294],{"class":94,"line":155},[92,1295,110],{"emptyLinePlaceholder":109},[92,1297,1298,1301,1303,1305],{"class":94,"line":161},[92,1299,1300],{"class":119},"$total ",[92,1302,126],{"class":98},[92,1304,1286],{"class":102},[92,1306,229],{"class":119},[92,1308,1309,1311,1313,1316,1318],{"class":94,"line":166},[92,1310,1300],{"class":119},[92,1312,1182],{"class":98},[92,1314,1315],{"class":102}," 5",[92,1317,309],{"class":119},[92,1319,1320],{"class":134},"// 15\n",[92,1322,1323,1325,1327,1330,1332],{"class":94,"line":187},[92,1324,1300],{"class":119},[92,1326,1195],{"class":98},[92,1328,1329],{"class":171}," '!'",[92,1331,975],{"class":119},[92,1333,1334],{"class":134},"// '15!'  (.= concatenates onto a string)\n",[242,1336,1338],{"id":1337},"comparison","Comparison",[11,1340,1341,1342,1345,1346,1349,1350,1353,1354,1357,1358,1361,1362,1365,1366,1369,1370,195,1373,1375,1376,1378],{},"Comparison is where PHP diverges most from other languages, so keep two operators sharp: ",[15,1343,1344],{},"=="," compares after type juggling (so ",[15,1347,1348],{},"\"1\" == 1"," is true), while ",[15,1351,1352],{},"==="," requires the same type and value with no conversion. The inverses are ",[15,1355,1356],{},"!="," (or ",[15,1359,1360],{},"\u003C>",") and ",[15,1363,1364],{},"!==",". The spaceship operator ",[15,1367,1368],{},"\u003C=>"," returns ",[15,1371,1372],{},"-1",[15,1374,554],{},", or ",[15,1377,68],{}," depending on ordering, which is exactly what a custom sort comparator needs to return.",[83,1380,1382],{"className":85,"code":1381,"language":87,"meta":88,"style":88},"1 == '1';    // true:  loose, string juggled to number\n1 === '1';   // false: different types\n1 != 2;      // true\n1 !== '1';   // true:  strict inequality\n\n3 \u003C=> 5;     // -1  (left is less)\n5 \u003C=> 5;     //  0  (equal)\n7 \u003C=> 5;     //  1  (left is greater)\n",[15,1383,1384,1399,1413,1426,1440,1444,1459,1473],{"__ignoreMap":88},[92,1385,1386,1388,1391,1394,1396],{"class":94,"line":95},[92,1387,68],{"class":102},[92,1389,1390],{"class":98}," ==",[92,1392,1393],{"class":171}," '1'",[92,1395,211],{"class":119},[92,1397,1398],{"class":134},"// true:  loose, string juggled to number\n",[92,1400,1401,1403,1406,1408,1410],{"class":94,"line":106},[92,1402,68],{"class":102},[92,1404,1405],{"class":98}," ===",[92,1407,1393],{"class":171},[92,1409,309],{"class":119},[92,1411,1412],{"class":134},"// false: different types\n",[92,1414,1415,1417,1420,1422,1424],{"class":94,"line":113},[92,1416,68],{"class":102},[92,1418,1419],{"class":98}," !=",[92,1421,1225],{"class":102},[92,1423,946],{"class":119},[92,1425,574],{"class":134},[92,1427,1428,1430,1433,1435,1437],{"class":94,"line":138},[92,1429,68],{"class":102},[92,1431,1432],{"class":98}," !==",[92,1434,1393],{"class":171},[92,1436,309],{"class":119},[92,1438,1439],{"class":134},"// true:  strict inequality\n",[92,1441,1442],{"class":94,"line":143},[92,1443,110],{"emptyLinePlaceholder":109},[92,1445,1446,1449,1452,1454,1456],{"class":94,"line":149},[92,1447,1448],{"class":102},"3",[92,1450,1451],{"class":98}," \u003C=>",[92,1453,1315],{"class":102},[92,1455,724],{"class":119},[92,1457,1458],{"class":134},"// -1  (left is less)\n",[92,1460,1461,1464,1466,1468,1470],{"class":94,"line":155},[92,1462,1463],{"class":102},"5",[92,1465,1451],{"class":98},[92,1467,1315],{"class":102},[92,1469,724],{"class":119},[92,1471,1472],{"class":134},"//  0  (equal)\n",[92,1474,1475,1477,1479,1481,1483],{"class":94,"line":161},[92,1476,1205],{"class":102},[92,1478,1451],{"class":98},[92,1480,1315],{"class":102},[92,1482,724],{"class":119},[92,1484,1485],{"class":134},"//  1  (left is greater)\n",[242,1487,1489],{"id":1488},"logical-operators","Logical operators",[11,1491,1492,1493,195,1496,394,1499,1502,1503,834,1506,1509,1510,1514,1515,1517,1518,1521,1522,1524,1525,1528,1529,1531],{},"The logical operators come in two spellings, and mixing them up causes a genuinely surprising bug. Prefer ",[15,1494,1495],{},"&&",[15,1497,1498],{},"||",[15,1500,1501],{},"!",", which bind tightly. The word forms ",[15,1504,1505],{},"and",[15,1507,1508],{},"or"," exist but have ",[1511,1512,1513],"em",{},"lower"," precedence than ",[15,1516,126],{},", so ",[15,1519,1520],{},"$x = true and false"," assigns ",[15,1523,474],{}," to ",[15,1526,1527],{},"$x"," (the assignment happens before the ",[15,1530,1505],{},"), which is almost never what you intend.",[83,1533,1535],{"className":85,"code":1534,"language":87,"meta":88,"style":88},"true && false;   // false\ntrue || false;   // true\n!true;           // false\n\n$ok = isset($a) && $a > 0;   // correct: && binds tighter than =\n$bad = true and false;       // $bad is TRUE, a classic precedence trap\n",[15,1536,1537,1551,1564,1575,1579,1607],{"__ignoreMap":88},[92,1538,1539,1541,1544,1547,1549],{"class":94,"line":95},[92,1540,474],{"class":102},[92,1542,1543],{"class":98}," &&",[92,1545,1546],{"class":102}," false",[92,1548,309],{"class":119},[92,1550,1082],{"class":134},[92,1552,1553,1555,1558,1560,1562],{"class":94,"line":106},[92,1554,474],{"class":102},[92,1556,1557],{"class":98}," ||",[92,1559,1546],{"class":102},[92,1561,309],{"class":119},[92,1563,574],{"class":134},[92,1565,1566,1568,1570,1573],{"class":94,"line":113},[92,1567,1501],{"class":98},[92,1569,474],{"class":102},[92,1571,1572],{"class":119},";           ",[92,1574,1082],{"class":134},[92,1576,1577],{"class":94,"line":138},[92,1578,110],{"emptyLinePlaceholder":109},[92,1580,1581,1584,1586,1589,1592,1594,1597,1600,1602,1604],{"class":94,"line":143},[92,1582,1583],{"class":119},"$ok ",[92,1585,126],{"class":98},[92,1587,1588],{"class":102}," isset",[92,1590,1591],{"class":119},"($a) ",[92,1593,1495],{"class":98},[92,1595,1596],{"class":119}," $a ",[92,1598,1599],{"class":98},">",[92,1601,331],{"class":102},[92,1603,309],{"class":119},[92,1605,1606],{"class":134},"// correct: && binds tighter than =\n",[92,1608,1609,1612,1614,1616,1619,1621,1623],{"class":94,"line":149},[92,1610,1611],{"class":119},"$bad ",[92,1613,126],{"class":98},[92,1615,295],{"class":102},[92,1617,1618],{"class":98}," and",[92,1620,1546],{"class":102},[92,1622,689],{"class":119},[92,1624,1625],{"class":134},"// $bad is TRUE, a classic precedence trap\n",[242,1627,1629],{"id":1628},"null-handling-and-the-ternary","Null handling and the ternary",[11,1631,1632,1633,1636,1637,1640,1641,1644,1645,1647,1648,1651,1652,987,1654,1656,1657,1660,1661,1663],{},"PHP has a dense set of operators for \"use this value unless it is missing,\" and the distinction between them matters. The full ternary ",[15,1634,1635],{},"cond ? a : b"," chooses between two values; the short ternary ",[15,1638,1639],{},"a ?: b"," falls back on any ",[1511,1642,1643],{},"falsy"," ",[15,1646,23],{},"; the null coalescing operator ",[15,1649,1650],{},"a ?? b"," falls back only when ",[15,1653,23],{},[15,1655,390],{}," or undefined (and never raises a warning for a missing key); and the null-safe operator ",[15,1658,1659],{},"?->"," short-circuits a method or property chain to ",[15,1662,390],{}," instead of erroring on a null object.",[83,1665,1667],{"className":85,"code":1666,"language":87,"meta":88,"style":88},"$status = $age >= 18 ? 'adult' : 'minor';   // full ternary\n$name = $input ?: 'guest';        // short ternary: falls back on any falsy value\n$name = $input ?? 'guest';        // null coalescing: falls back only on null/undefined\n$config['timeout'] ??= 30;        // assign only if unset or null\n$city = $user?->address?->city;   // null-safe: null if any link is null, no error\n",[15,1668,1669,1701,1723,1741,1763],{"__ignoreMap":88},[92,1670,1671,1674,1676,1679,1682,1685,1688,1691,1693,1696,1698],{"class":94,"line":95},[92,1672,1673],{"class":119},"$status ",[92,1675,126],{"class":98},[92,1677,1678],{"class":119}," $age ",[92,1680,1681],{"class":98},">=",[92,1683,1684],{"class":102}," 18",[92,1686,1687],{"class":98}," ?",[92,1689,1690],{"class":171}," 'adult'",[92,1692,903],{"class":98},[92,1694,1695],{"class":171}," 'minor'",[92,1697,309],{"class":119},[92,1699,1700],{"class":134},"// full ternary\n",[92,1702,1703,1706,1708,1711,1714,1717,1720],{"class":94,"line":106},[92,1704,1705],{"class":119},"$name ",[92,1707,126],{"class":98},[92,1709,1710],{"class":119}," $input ",[92,1712,1713],{"class":98},"?:",[92,1715,1716],{"class":171}," 'guest'",[92,1718,1719],{"class":119},";        ",[92,1721,1722],{"class":134},"// short ternary: falls back on any falsy value\n",[92,1724,1725,1727,1729,1731,1734,1736,1738],{"class":94,"line":113},[92,1726,1705],{"class":119},[92,1728,126],{"class":98},[92,1730,1710],{"class":119},[92,1732,1733],{"class":98},"??",[92,1735,1716],{"class":171},[92,1737,1719],{"class":119},[92,1739,1740],{"class":134},"// null coalescing: falls back only on null/undefined\n",[92,1742,1743,1746,1749,1752,1755,1758,1760],{"class":94,"line":138},[92,1744,1745],{"class":119},"$config[",[92,1747,1748],{"class":171},"'timeout'",[92,1750,1751],{"class":119},"] ",[92,1753,1754],{"class":98},"??=",[92,1756,1757],{"class":102}," 30",[92,1759,1719],{"class":119},[92,1761,1762],{"class":134},"// assign only if unset or null\n",[92,1764,1765,1768,1770,1773,1775,1778,1780,1783],{"class":94,"line":143},[92,1766,1767],{"class":119},"$city ",[92,1769,126],{"class":98},[92,1771,1772],{"class":119}," $user",[92,1774,1659],{"class":98},[92,1776,1777],{"class":119},"address",[92,1779,1659],{"class":98},[92,1781,1782],{"class":119},"city;   ",[92,1784,1785],{"class":134},"// null-safe: null if any link is null, no error\n",[242,1787,1789],{"id":1788},"array-bitwise-and-type-operators","Array, bitwise, and type operators",[11,1791,1792,1793,1796,1797,1800,1801,1804,1805,195,1808,195,1811,195,1814,195,1817,195,1820,1823,1824,1827,1828,1831],{},"The ",[15,1794,1795],{},"+"," operator on two arrays is a ",[1511,1798,1799],{},"union"," that keeps the left side's value for any duplicate key, which behaves very differently from ",[15,1802,1803],{},"array_merge()"," (see the gotchas). The bitwise operators (",[15,1806,1807],{},"&",[15,1809,1810],{},"|",[15,1812,1813],{},"^",[15,1815,1816],{},"~",[15,1818,1819],{},"\u003C\u003C",[15,1821,1822],{},">>",") work on integers, ",[15,1825,1826],{},"instanceof"," tests an object's class or interface, and ",[15,1829,1830],{},"@"," suppresses errors on a single expression (an anti-pattern you should recognize but avoid).",[83,1833,1835],{"className":85,"code":1834,"language":87,"meta":88,"style":88},"['a' => 1, 'b' => 2] + ['b' => 9, 'c' => 3];  // ['a'=>1, 'b'=>2, 'c'=>3]; left wins on 'b'\n\n6 & 3;    // 2   (bitwise AND)\n6 | 1;    // 7   (bitwise OR)\n1 \u003C\u003C 4;   // 16  (left shift, i.e. 1 * 2**4)\n\n$e instanceof RuntimeException;   // true if $e is that class or a subclass\n",[15,1836,1837,1885,1889,1903,1917,1932,1936],{"__ignoreMap":88},[92,1838,1839,1842,1845,1847,1850,1852,1854,1856,1858,1860,1862,1864,1866,1868,1871,1873,1875,1877,1879,1882],{"class":94,"line":95},[92,1840,1841],{"class":119},"[",[92,1843,1844],{"class":171},"'a'",[92,1846,1019],{"class":98},[92,1848,1849],{"class":102}," 1",[92,1851,195],{"class":119},[92,1853,198],{"class":171},[92,1855,1019],{"class":98},[92,1857,1225],{"class":102},[92,1859,1751],{"class":119},[92,1861,1795],{"class":98},[92,1863,347],{"class":119},[92,1865,198],{"class":171},[92,1867,1019],{"class":98},[92,1869,1870],{"class":102}," 9",[92,1872,195],{"class":119},[92,1874,203],{"class":171},[92,1876,1019],{"class":98},[92,1878,856],{"class":102},[92,1880,1881],{"class":119},"];  ",[92,1883,1884],{"class":134},"// ['a'=>1, 'b'=>2, 'c'=>3]; left wins on 'b'\n",[92,1886,1887],{"class":94,"line":106},[92,1888,110],{"emptyLinePlaceholder":109},[92,1890,1891,1893,1896,1898,1900],{"class":94,"line":113},[92,1892,1235],{"class":102},[92,1894,1895],{"class":98}," &",[92,1897,856],{"class":102},[92,1899,211],{"class":119},[92,1901,1902],{"class":134},"// 2   (bitwise AND)\n",[92,1904,1905,1907,1910,1912,1914],{"class":94,"line":138},[92,1906,1235],{"class":102},[92,1908,1909],{"class":98}," |",[92,1911,1849],{"class":102},[92,1913,211],{"class":119},[92,1915,1916],{"class":134},"// 7   (bitwise OR)\n",[92,1918,1919,1921,1924,1927,1929],{"class":94,"line":143},[92,1920,68],{"class":102},[92,1922,1923],{"class":98}," \u003C\u003C",[92,1925,1926],{"class":102}," 4",[92,1928,309],{"class":119},[92,1930,1931],{"class":134},"// 16  (left shift, i.e. 1 * 2**4)\n",[92,1933,1934],{"class":94,"line":149},[92,1935,110],{"emptyLinePlaceholder":109},[92,1937,1938,1941,1943,1946,1948],{"class":94,"line":155},[92,1939,1940],{"class":119},"$e ",[92,1942,1826],{"class":98},[92,1944,1945],{"class":102}," RuntimeException",[92,1947,309],{"class":119},[92,1949,1950],{"class":134},"// true if $e is that class or a subclass\n",[11,1952,1953,1954,1956,1957,834,1960,1956,1962,834,1964,1967,1968,1956,1970,1972],{},"Operator precedence follows the usual mathematical ordering (",[15,1955,1165],{}," before ",[15,1958,1959],{},"*",[15,1961,529],{},[15,1963,1795],{},[15,1965,1966],{},"-",", comparison before ",[15,1969,1495],{},[15,1971,1498],{},"), but PHP 8 made one rule strict: a nested ternary must be parenthesized, because the old left-associative behavior was a frequent source of bugs.",[39,1974,1976],{"id":1975},"strings","Strings",[242,1978,1980],{"id":1979},"quotes-interpolation-and-heredoc","Quotes, interpolation, and heredoc",[11,1982,1983,1984,834,1986,1989,1990,1993,1994,1997,1998,2001,2002,2005],{},"Single quotes produce a literal string, while double quotes interpolate variables and process escape sequences like ",[15,1985,175],{},[15,1987,1988],{},"\\t","; this is a real semantic difference, not a style choice. Wrap a variable in ",[15,1991,1992],{},"{}"," inside a double-quoted string when the surrounding characters would otherwise be read as part of the name, and use ",[15,1995,1996],{},"->"," interpolation for object properties. For multi-line blocks, heredoc (",[15,1999,2000],{},"\u003C\u003C\u003CTAG",") behaves like a double-quoted string and nowdoc (",[15,2003,2004],{},"\u003C\u003C\u003C'TAG'",") behaves like a single-quoted one.",[83,2007,2009],{"className":85,"code":2008,"language":87,"meta":88,"style":88},"$name = 'Ada';\necho 'Hello $name';        // literal:      Hello $name\necho \"Hello $name\\n\";      // interpolated: Hello Ada + newline\necho \"Hi {$name}s\";        // braces disambiguate: Hi Adas\necho \"City: {$user->city}\"; // property interpolation\n\n$greeting = 'Hello, ' . $name . '!';   // concatenate with '.', never '+'\n\n$html = \u003C\u003C\u003CHTML\n    \u003Cp>Hello, $name\u003C/p>\n    HTML;                  // heredoc interpolates like double quotes\n\n$raw = \u003C\u003C\u003C'TXT'\n    Literal $name, no interpolation here.\n    TXT;                   // nowdoc is literal\n",[15,2010,2011,2021,2033,2052,2069,2092,2096,2121,2125,2138,2159,2170,2174,2190,2195],{"__ignoreMap":88},[92,2012,2013,2015,2017,2019],{"class":94,"line":95},[92,2014,1705],{"class":119},[92,2016,126],{"class":98},[92,2018,271],{"class":171},[92,2020,229],{"class":119},[92,2022,2023,2025,2028,2030],{"class":94,"line":106},[92,2024,60],{"class":102},[92,2026,2027],{"class":171}," 'Hello $name'",[92,2029,1719],{"class":119},[92,2031,2032],{"class":134},"// literal:      Hello $name\n",[92,2034,2035,2037,2040,2043,2045,2047,2049],{"class":94,"line":113},[92,2036,60],{"class":102},[92,2038,2039],{"class":171}," \"Hello ",[92,2041,2042],{"class":119},"$name",[92,2044,175],{"class":102},[92,2046,178],{"class":171},[92,2048,946],{"class":119},[92,2050,2051],{"class":134},"// interpolated: Hello Ada + newline\n",[92,2053,2054,2056,2059,2061,2064,2066],{"class":94,"line":138},[92,2055,60],{"class":102},[92,2057,2058],{"class":171}," \"Hi {",[92,2060,2042],{"class":119},[92,2062,2063],{"class":171},"}s\"",[92,2065,1719],{"class":119},[92,2067,2068],{"class":134},"// braces disambiguate: Hi Adas\n",[92,2070,2071,2073,2076,2079,2081,2084,2087,2089],{"class":94,"line":143},[92,2072,60],{"class":102},[92,2074,2075],{"class":171}," \"City: {",[92,2077,2078],{"class":119},"$user",[92,2080,1996],{"class":98},[92,2082,2083],{"class":119},"city",[92,2085,2086],{"class":171},"}\"",[92,2088,975],{"class":119},[92,2090,2091],{"class":134},"// property interpolation\n",[92,2093,2094],{"class":94,"line":149},[92,2095,110],{"emptyLinePlaceholder":109},[92,2097,2098,2101,2103,2106,2109,2112,2114,2116,2118],{"class":94,"line":155},[92,2099,2100],{"class":119},"$greeting ",[92,2102,126],{"class":98},[92,2104,2105],{"class":171}," 'Hello, '",[92,2107,2108],{"class":98}," .",[92,2110,2111],{"class":119}," $name ",[92,2113,81],{"class":98},[92,2115,1329],{"class":171},[92,2117,309],{"class":119},[92,2119,2120],{"class":134},"// concatenate with '.', never '+'\n",[92,2122,2123],{"class":94,"line":161},[92,2124,110],{"emptyLinePlaceholder":109},[92,2126,2127,2130,2132,2135],{"class":94,"line":166},[92,2128,2129],{"class":119},"$html ",[92,2131,126],{"class":98},[92,2133,2134],{"class":171}," \u003C\u003C\u003C",[92,2136,2137],{"class":98},"HTML\n",[92,2139,2140,2143,2146,2149,2151,2154,2156],{"class":94,"line":187},[92,2141,2142],{"class":171},"    \u003C",[92,2144,11],{"class":2145},"s4JwU",[92,2147,2148],{"class":171},">Hello, ",[92,2150,2042],{"class":119},[92,2152,2153],{"class":171},"\u003C/",[92,2155,11],{"class":2145},[92,2157,2158],{"class":171},">\n",[92,2160,2161,2164,2167],{"class":94,"line":217},[92,2162,2163],{"class":98},"    HTML",[92,2165,2166],{"class":119},";                  ",[92,2168,2169],{"class":134},"// heredoc interpolates like double quotes\n",[92,2171,2172],{"class":94,"line":712},[92,2173,110],{"emptyLinePlaceholder":109},[92,2175,2176,2179,2181,2184,2187],{"class":94,"line":730},[92,2177,2178],{"class":119},"$raw ",[92,2180,126],{"class":98},[92,2182,2183],{"class":171}," \u003C\u003C\u003C'",[92,2185,2186],{"class":98},"TXT",[92,2188,2189],{"class":171},"'\n",[92,2191,2192],{"class":94,"line":747},[92,2193,2194],{"class":171},"    Literal $name, no interpolation here.\n",[92,2196,2197,2200,2203],{"class":94,"line":763},[92,2198,2199],{"class":98},"    TXT",[92,2201,2202],{"class":119},";                   ",[92,2204,2205],{"class":134},"// nowdoc is literal\n",[242,2207,2209],{"id":2208},"accessing-characters","Accessing characters",[11,2211,2212,2213,2216,2217,2220],{},"A string is indexable like an array of single-byte characters, and PHP supports negative indices that count from the end, which is handy for grabbing the last character. Keep in mind that this indexes ",[1511,2214,2215],{},"bytes",", not Unicode code points, so it is only safe for ASCII; use the ",[15,2218,2219],{},"mb_*"," functions for multibyte text.",[83,2222,2224],{"className":85,"code":2223,"language":87,"meta":88,"style":88},"$s = 'hello';\n$s[0];    // 'h'\n$s[-1];   // 'o'  (negative index counts from the end)\n$s[1] = 'a';  // strings are mutable by index: $s is now 'hallo'\n",[15,2225,2226,2238,2251,2265],{"__ignoreMap":88},[92,2227,2228,2231,2233,2236],{"class":94,"line":95},[92,2229,2230],{"class":119},"$s ",[92,2232,126],{"class":98},[92,2234,2235],{"class":171}," 'hello'",[92,2237,229],{"class":119},[92,2239,2240,2243,2245,2248],{"class":94,"line":106},[92,2241,2242],{"class":119},"$s[",[92,2244,554],{"class":102},[92,2246,2247],{"class":119},"];    ",[92,2249,2250],{"class":134},"// 'h'\n",[92,2252,2253,2255,2257,2259,2262],{"class":94,"line":113},[92,2254,2242],{"class":119},[92,2256,1966],{"class":98},[92,2258,68],{"class":102},[92,2260,2261],{"class":119},"];   ",[92,2263,2264],{"class":134},"// 'o'  (negative index counts from the end)\n",[92,2266,2267,2269,2271,2273,2275,2277,2280],{"class":94,"line":138},[92,2268,2242],{"class":119},[92,2270,68],{"class":102},[92,2272,1751],{"class":119},[92,2274,126],{"class":98},[92,2276,192],{"class":171},[92,2278,2279],{"class":119},";  ",[92,2281,2282],{"class":134},"// strings are mutable by index: $s is now 'hallo'\n",[242,2284,2286],{"id":2285},"common-string-functions","Common string functions",[11,2288,2289,2290,2293,2294,2297,2298,81],{},"Strings are a scalar type, not an object, so their operations are global functions rather than methods. The set below covers the vast majority of what a coding exercise needs: measuring, changing case, trimming, searching, replacing, splitting, joining, and formatting. Note that ",[15,2291,2292],{},"strlen()"," counts bytes (use ",[15,2295,2296],{},"mb_strlen()"," for characters) and that the search functions return a byte index or ",[15,2299,2300],{},"false",[83,2302,2304],{"className":85,"code":2303,"language":87,"meta":88,"style":88},"strlen('hello');                  // 5   (bytes; use mb_strlen for UTF-8)\nstrtoupper('hi');                 // 'HI'\nstrtolower('HI');                 // 'hi'\nucfirst('hello');                 // 'Hello'\nucwords('hello world');           // 'Hello World'\ntrim('  hi  ');                   // 'hi'   (also ltrim, rtrim)\ntrim('__hi__', '_');              // 'hi'   (trim custom characters)\n\nsubstr('hello', 1, 3);            // 'ell' (start index, length)\nstrpos('hello', 'l');             // 2     (index, or false if absent)\nstrrpos('hello', 'l');            // 3     (last occurrence)\nstr_contains('hello', 'ell');     // true  (PHP 8.0+)\nstr_starts_with('hello', 'he');   // true  (PHP 8.0+)\nstr_ends_with('hello', 'lo');     // true  (PHP 8.0+)\n\nstr_replace('l', 'L', 'hello');   // 'heLLo'\nsubstr_count('hello', 'l');       // 2\nstr_repeat('ab', 3);              // 'ababab'\nstr_pad('5', 3, '0', STR_PAD_LEFT); // '005'\nstrrev('abc');                    // 'cba'\nstr_split('abcd', 2);             // ['ab', 'cd']\n\nexplode(',', 'a,b,c');            // ['a', 'b', 'c']\nimplode('-', ['a', 'b', 'c']);    // 'a-b-c'  (join is an alias)\nsprintf('%s is %d (%.1f%%)', 'x', 3, 42.5); // 'x is 3 (42.5%)'\nnumber_format(1234567.891, 2);    // '1,234,567.89'\nhtmlspecialchars('\u003Ca href=\"x\">'); // '&lt;a href=&quot;x&quot;&gt;'\n",[15,2305,2306,2322,2337,2352,2366,2382,2398,2418,2422,2445,2465,2483,2502,2520,2538,2542,2565,2583,2603,2632,2649,2669,2674,2695,2724,2753,2774],{"__ignoreMap":88},[92,2307,2308,2311,2313,2316,2319],{"class":94,"line":95},[92,2309,2310],{"class":102},"strlen",[92,2312,120],{"class":119},[92,2314,2315],{"class":171},"'hello'",[92,2317,2318],{"class":119},");                  ",[92,2320,2321],{"class":134},"// 5   (bytes; use mb_strlen for UTF-8)\n",[92,2323,2324,2327,2329,2331,2334],{"class":94,"line":106},[92,2325,2326],{"class":102},"strtoupper",[92,2328,120],{"class":119},[92,2330,460],{"class":171},[92,2332,2333],{"class":119},");                 ",[92,2335,2336],{"class":134},"// 'HI'\n",[92,2338,2339,2342,2344,2347,2349],{"class":94,"line":113},[92,2340,2341],{"class":102},"strtolower",[92,2343,120],{"class":119},[92,2345,2346],{"class":171},"'HI'",[92,2348,2333],{"class":119},[92,2350,2351],{"class":134},"// 'hi'\n",[92,2353,2354,2357,2359,2361,2363],{"class":94,"line":138},[92,2355,2356],{"class":102},"ucfirst",[92,2358,120],{"class":119},[92,2360,2315],{"class":171},[92,2362,2333],{"class":119},[92,2364,2365],{"class":134},"// 'Hello'\n",[92,2367,2368,2371,2373,2376,2379],{"class":94,"line":143},[92,2369,2370],{"class":102},"ucwords",[92,2372,120],{"class":119},[92,2374,2375],{"class":171},"'hello world'",[92,2377,2378],{"class":119},");           ",[92,2380,2381],{"class":134},"// 'Hello World'\n",[92,2383,2384,2387,2389,2392,2395],{"class":94,"line":149},[92,2385,2386],{"class":102},"trim",[92,2388,120],{"class":119},[92,2390,2391],{"class":171},"'  hi  '",[92,2393,2394],{"class":119},");                   ",[92,2396,2397],{"class":134},"// 'hi'   (also ltrim, rtrim)\n",[92,2399,2400,2402,2404,2407,2409,2412,2415],{"class":94,"line":155},[92,2401,2386],{"class":102},[92,2403,120],{"class":119},[92,2405,2406],{"class":171},"'__hi__'",[92,2408,195],{"class":119},[92,2410,2411],{"class":171},"'_'",[92,2413,2414],{"class":119},");              ",[92,2416,2417],{"class":134},"// 'hi'   (trim custom characters)\n",[92,2419,2420],{"class":94,"line":161},[92,2421,110],{"emptyLinePlaceholder":109},[92,2423,2424,2427,2429,2431,2433,2435,2437,2439,2442],{"class":94,"line":166},[92,2425,2426],{"class":102},"substr",[92,2428,120],{"class":119},[92,2430,2315],{"class":171},[92,2432,195],{"class":119},[92,2434,68],{"class":102},[92,2436,195],{"class":119},[92,2438,1448],{"class":102},[92,2440,2441],{"class":119},");            ",[92,2443,2444],{"class":134},"// 'ell' (start index, length)\n",[92,2446,2447,2450,2452,2454,2456,2459,2462],{"class":94,"line":187},[92,2448,2449],{"class":102},"strpos",[92,2451,120],{"class":119},[92,2453,2315],{"class":171},[92,2455,195],{"class":119},[92,2457,2458],{"class":171},"'l'",[92,2460,2461],{"class":119},");             ",[92,2463,2464],{"class":134},"// 2     (index, or false if absent)\n",[92,2466,2467,2470,2472,2474,2476,2478,2480],{"class":94,"line":217},[92,2468,2469],{"class":102},"strrpos",[92,2471,120],{"class":119},[92,2473,2315],{"class":171},[92,2475,195],{"class":119},[92,2477,2458],{"class":171},[92,2479,2441],{"class":119},[92,2481,2482],{"class":134},"// 3     (last occurrence)\n",[92,2484,2485,2488,2490,2492,2494,2497,2499],{"class":94,"line":712},[92,2486,2487],{"class":102},"str_contains",[92,2489,120],{"class":119},[92,2491,2315],{"class":171},[92,2493,195],{"class":119},[92,2495,2496],{"class":171},"'ell'",[92,2498,599],{"class":119},[92,2500,2501],{"class":134},"// true  (PHP 8.0+)\n",[92,2503,2504,2507,2509,2511,2513,2516,2518],{"class":94,"line":730},[92,2505,2506],{"class":102},"str_starts_with",[92,2508,120],{"class":119},[92,2510,2315],{"class":171},[92,2512,195],{"class":119},[92,2514,2515],{"class":171},"'he'",[92,2517,131],{"class":119},[92,2519,2501],{"class":134},[92,2521,2522,2525,2527,2529,2531,2534,2536],{"class":94,"line":747},[92,2523,2524],{"class":102},"str_ends_with",[92,2526,120],{"class":119},[92,2528,2315],{"class":171},[92,2530,195],{"class":119},[92,2532,2533],{"class":171},"'lo'",[92,2535,599],{"class":119},[92,2537,2501],{"class":134},[92,2539,2540],{"class":94,"line":763},[92,2541,110],{"emptyLinePlaceholder":109},[92,2543,2544,2547,2549,2551,2553,2556,2558,2560,2562],{"class":94,"line":780},[92,2545,2546],{"class":102},"str_replace",[92,2548,120],{"class":119},[92,2550,2458],{"class":171},[92,2552,195],{"class":119},[92,2554,2555],{"class":171},"'L'",[92,2557,195],{"class":119},[92,2559,2315],{"class":171},[92,2561,131],{"class":119},[92,2563,2564],{"class":134},"// 'heLLo'\n",[92,2566,2567,2570,2572,2574,2576,2578,2580],{"class":94,"line":785},[92,2568,2569],{"class":102},"substr_count",[92,2571,120],{"class":119},[92,2573,2315],{"class":171},[92,2575,195],{"class":119},[92,2577,2458],{"class":171},[92,2579,613],{"class":119},[92,2581,2582],{"class":134},"// 2\n",[92,2584,2586,2589,2591,2594,2596,2598,2600],{"class":94,"line":2585},18,[92,2587,2588],{"class":102},"str_repeat",[92,2590,120],{"class":119},[92,2592,2593],{"class":171},"'ab'",[92,2595,195],{"class":119},[92,2597,1448],{"class":102},[92,2599,2414],{"class":119},[92,2601,2602],{"class":134},"// 'ababab'\n",[92,2604,2606,2609,2611,2614,2616,2618,2620,2622,2624,2627,2629],{"class":94,"line":2605},19,[92,2607,2608],{"class":102},"str_pad",[92,2610,120],{"class":119},[92,2612,2613],{"class":171},"'5'",[92,2615,195],{"class":119},[92,2617,1448],{"class":102},[92,2619,195],{"class":119},[92,2621,739],{"class":171},[92,2623,195],{"class":119},[92,2625,2626],{"class":102},"STR_PAD_LEFT",[92,2628,653],{"class":119},[92,2630,2631],{"class":134},"// '005'\n",[92,2633,2635,2638,2640,2643,2646],{"class":94,"line":2634},20,[92,2636,2637],{"class":102},"strrev",[92,2639,120],{"class":119},[92,2641,2642],{"class":171},"'abc'",[92,2644,2645],{"class":119},");                    ",[92,2647,2648],{"class":134},"// 'cba'\n",[92,2650,2652,2655,2657,2660,2662,2664,2666],{"class":94,"line":2651},21,[92,2653,2654],{"class":102},"str_split",[92,2656,120],{"class":119},[92,2658,2659],{"class":171},"'abcd'",[92,2661,195],{"class":119},[92,2663,354],{"class":102},[92,2665,2461],{"class":119},[92,2667,2668],{"class":134},"// ['ab', 'cd']\n",[92,2670,2672],{"class":94,"line":2671},22,[92,2673,110],{"emptyLinePlaceholder":109},[92,2675,2677,2680,2682,2685,2687,2690,2692],{"class":94,"line":2676},23,[92,2678,2679],{"class":102},"explode",[92,2681,120],{"class":119},[92,2683,2684],{"class":171},"','",[92,2686,195],{"class":119},[92,2688,2689],{"class":171},"'a,b,c'",[92,2691,2441],{"class":119},[92,2693,2694],{"class":134},"// ['a', 'b', 'c']\n",[92,2696,2698,2701,2703,2706,2709,2711,2713,2715,2717,2719,2721],{"class":94,"line":2697},24,[92,2699,2700],{"class":102},"implode",[92,2702,120],{"class":119},[92,2704,2705],{"class":171},"'-'",[92,2707,2708],{"class":119},", [",[92,2710,1844],{"class":171},[92,2712,195],{"class":119},[92,2714,198],{"class":171},[92,2716,195],{"class":119},[92,2718,203],{"class":171},[92,2720,495],{"class":119},[92,2722,2723],{"class":134},"// 'a-b-c'  (join is an alias)\n",[92,2725,2727,2730,2732,2735,2737,2739,2741,2743,2745,2748,2750],{"class":94,"line":2726},25,[92,2728,2729],{"class":102},"sprintf",[92,2731,120],{"class":119},[92,2733,2734],{"class":171},"'%s is %d (%.1f%%)'",[92,2736,195],{"class":119},[92,2738,772],{"class":171},[92,2740,195],{"class":119},[92,2742,1448],{"class":102},[92,2744,195],{"class":119},[92,2746,2747],{"class":102},"42.5",[92,2749,653],{"class":119},[92,2751,2752],{"class":134},"// 'x is 3 (42.5%)'\n",[92,2754,2756,2759,2761,2764,2766,2768,2771],{"class":94,"line":2755},26,[92,2757,2758],{"class":102},"number_format",[92,2760,120],{"class":119},[92,2762,2763],{"class":102},"1234567.891",[92,2765,195],{"class":119},[92,2767,354],{"class":102},[92,2769,2770],{"class":119},");    ",[92,2772,2773],{"class":134},"// '1,234,567.89'\n",[92,2775,2777,2780,2782,2785,2787],{"class":94,"line":2776},27,[92,2778,2779],{"class":102},"htmlspecialchars",[92,2781,120],{"class":119},[92,2783,2784],{"class":171},"'\u003Ca href=\"x\">'",[92,2786,653],{"class":119},[92,2788,2789],{"class":134},"// '&lt;a href=&quot;x&quot;&gt;'\n",[242,2791,2793],{"id":2792},"validating-string-content","Validating string content",[11,2795,2796,2797,2800],{},"For quick input validation without regex, the ",[15,2798,2799],{},"ctype_*"," functions test whether every character in a string belongs to a class, which is cleaner than writing a pattern for simple checks. Be aware that they behave oddly when passed an integer (they treat it as an ASCII code), so pass strings.",[83,2802,2804],{"className":85,"code":2803,"language":87,"meta":88,"style":88},"ctype_digit('12345');   // true:  all digits\nctype_alpha('abcDEF');  // true:  all letters\nctype_alnum('abc123');  // true:  letters and digits\nctype_space(\"  \\t\\n\");  // true:  all whitespace\n",[15,2805,2806,2821,2836,2851],{"__ignoreMap":88},[92,2807,2808,2811,2813,2816,2818],{"class":94,"line":95},[92,2809,2810],{"class":102},"ctype_digit",[92,2812,120],{"class":119},[92,2814,2815],{"class":171},"'12345'",[92,2817,131],{"class":119},[92,2819,2820],{"class":134},"// true:  all digits\n",[92,2822,2823,2826,2828,2831,2833],{"class":94,"line":106},[92,2824,2825],{"class":102},"ctype_alpha",[92,2827,120],{"class":119},[92,2829,2830],{"class":171},"'abcDEF'",[92,2832,800],{"class":119},[92,2834,2835],{"class":134},"// true:  all letters\n",[92,2837,2838,2841,2843,2846,2848],{"class":94,"line":113},[92,2839,2840],{"class":102},"ctype_alnum",[92,2842,120],{"class":119},[92,2844,2845],{"class":171},"'abc123'",[92,2847,800],{"class":119},[92,2849,2850],{"class":134},"// true:  letters and digits\n",[92,2852,2853,2856,2858,2861,2864,2866,2868],{"class":94,"line":138},[92,2854,2855],{"class":102},"ctype_space",[92,2857,120],{"class":119},[92,2859,2860],{"class":171},"\"  ",[92,2862,2863],{"class":102},"\\t\\n",[92,2865,178],{"class":171},[92,2867,800],{"class":119},[92,2869,2870],{"class":134},"// true:  all whitespace\n",[11,2872,2873,2874,1369,2877,2879,2880,2883,2884,2886,2887,2890,2891,2894],{},"String parsing shows up constantly in coding rounds, and the trap worth memorizing is that ",[15,2875,2876],{},"strpos()",[15,2878,554],{}," for a match at the very start, which is falsy, so ",[15,2881,2882],{},"if (strpos(...))"," wrongly reports \"not found\" for position ",[15,2885,554],{},"; test with ",[15,2888,2889],{},"!== false",", or use ",[15,2892,2893],{},"str_contains()"," when you only need a yes/no answer.",[39,2896,2898],{"id":2897},"arrays","Arrays",[242,2900,2902],{"id":2901},"one-type-many-roles","One type, many roles",[11,2904,2905,2906,2908,2909,2912,2913,2916,2917,2920,2921,2924],{},"PHP has a single built-in collection type, the ",[15,2907,383],{},", and it is an ",[1511,2910,2911],{},"ordered map"," (a hash table with a remembered insertion order) rather than a fixed-size list. The same type serves as list, dictionary, stack, and queue: keys are either integers or strings, values are anything, and the order you insert is the order you iterate. This is the biggest adjustment coming from languages that separate ",[15,2914,2915],{},"List"," from ",[15,2918,2919],{},"Map",", because in PHP a \"list\" is simply an array whose keys happen to be ",[15,2922,2923],{},"0, 1, 2"," and up.",[83,2926,2928],{"className":85,"code":2927,"language":87,"meta":88,"style":88},"$list  = [1, 2, 3];                       // integer keys 0, 1, 2\n$assoc = ['name' => 'Ada', 'age' => 36];  // string keys\n$mixed = [0 => 'a', 'k' => 'b', 5 => 'c'];// keys can mix types; order is preserved\n$nested = [\n    ['name' => 'Ada',   'age' => 36],     // an array of arrays (rows)\n    ['name' => 'Linus', 'age' => 54],\n];\n$nested[1]['name'];   // 'Linus'\n",[15,2929,2930,2955,2985,3025,3035,3061,3084,3088],{"__ignoreMap":88},[92,2931,2932,2935,2937,2939,2941,2943,2945,2947,2949,2952],{"class":94,"line":95},[92,2933,2934],{"class":119},"$list  ",[92,2936,126],{"class":98},[92,2938,347],{"class":119},[92,2940,68],{"class":102},[92,2942,195],{"class":119},[92,2944,354],{"class":102},[92,2946,195],{"class":119},[92,2948,1448],{"class":102},[92,2950,2951],{"class":119},"];                       ",[92,2953,2954],{"class":134},"// integer keys 0, 1, 2\n",[92,2956,2957,2960,2962,2964,2966,2968,2970,2972,2975,2977,2980,2982],{"class":94,"line":106},[92,2958,2959],{"class":119},"$assoc ",[92,2961,126],{"class":98},[92,2963,347],{"class":119},[92,2965,1016],{"class":171},[92,2967,1019],{"class":98},[92,2969,271],{"class":171},[92,2971,195],{"class":119},[92,2973,2974],{"class":171},"'age'",[92,2976,1019],{"class":98},[92,2978,2979],{"class":102}," 36",[92,2981,1881],{"class":119},[92,2983,2984],{"class":134},"// string keys\n",[92,2986,2987,2990,2992,2994,2996,2998,3000,3002,3005,3007,3010,3012,3014,3016,3019,3022],{"class":94,"line":113},[92,2988,2989],{"class":119},"$mixed ",[92,2991,126],{"class":98},[92,2993,347],{"class":119},[92,2995,554],{"class":102},[92,2997,1019],{"class":98},[92,2999,192],{"class":171},[92,3001,195],{"class":119},[92,3003,3004],{"class":171},"'k'",[92,3006,1019],{"class":98},[92,3008,3009],{"class":171}," 'b'",[92,3011,195],{"class":119},[92,3013,1463],{"class":102},[92,3015,1019],{"class":98},[92,3017,3018],{"class":171}," 'c'",[92,3020,3021],{"class":119},"];",[92,3023,3024],{"class":134},"// keys can mix types; order is preserved\n",[92,3026,3027,3030,3032],{"class":94,"line":138},[92,3028,3029],{"class":119},"$nested ",[92,3031,126],{"class":98},[92,3033,3034],{"class":119}," [\n",[92,3036,3037,3040,3042,3044,3046,3049,3051,3053,3055,3058],{"class":94,"line":143},[92,3038,3039],{"class":119},"    [",[92,3041,1016],{"class":171},[92,3043,1019],{"class":98},[92,3045,271],{"class":171},[92,3047,3048],{"class":119},",   ",[92,3050,2974],{"class":171},[92,3052,1019],{"class":98},[92,3054,2979],{"class":102},[92,3056,3057],{"class":119},"],     ",[92,3059,3060],{"class":134},"// an array of arrays (rows)\n",[92,3062,3063,3065,3067,3069,3072,3074,3076,3078,3081],{"class":94,"line":149},[92,3064,3039],{"class":119},[92,3066,1016],{"class":171},[92,3068,1019],{"class":98},[92,3070,3071],{"class":171}," 'Linus'",[92,3073,195],{"class":119},[92,3075,2974],{"class":171},[92,3077,1019],{"class":98},[92,3079,3080],{"class":102}," 54",[92,3082,3083],{"class":119},"],\n",[92,3085,3086],{"class":94,"line":155},[92,3087,1034],{"class":119},[92,3089,3090,3093,3095,3098,3100,3102],{"class":94,"line":161},[92,3091,3092],{"class":119},"$nested[",[92,3094,68],{"class":102},[92,3096,3097],{"class":119},"][",[92,3099,1016],{"class":171},[92,3101,2261],{"class":119},[92,3103,3104],{"class":134},"// 'Linus'\n",[11,3106,3107],{},[3108,3109],"img",{"alt":3110,"src":3111},"PHP array shown as a single ordered map of integer and string keys to values","/post-images/php-syntax-recap/php-array-ordered-map.png",[242,3113,3115],{"id":3114},"adding-removing-and-inspecting-elements","Adding, removing, and inspecting elements",[11,3117,3118,3119,3122,3123,3126,3127,834,3130,3132,3133,834,3136,3139],{},"You append with the empty-bracket shorthand ",[15,3120,3121],{},"$arr[]",", which is idiomatic, or with ",[15,3124,3125],{},"array_push()"," when you want to add several at once. The four stack/queue functions matter for interview problems: ",[15,3128,3129],{},"array_pop()",[15,3131,3125],{}," work the fast end (the tail), while ",[15,3134,3135],{},"array_shift()",[15,3137,3138],{},"array_unshift()"," work the front and are O(n) because they renumber every integer key.",[83,3141,3143],{"className":85,"code":3142,"language":87,"meta":88,"style":88},"$a = [1, 2, 3];\n$a[] = 4;                 // append: [1, 2, 3, 4]\narray_push($a, 5, 6);     // append several: [1, 2, 3, 4, 5, 6]\narray_pop($a);            // remove and return the last (6); O(1)\narray_shift($a);          // remove and return the first (1); O(n), reindexes\narray_unshift($a, 0);     // prepend 0; O(n)\n\ncount($a);                // number of elements (sizeof is an alias)\nin_array(3, $a);          // true: value membership\nin_array('3', $a, true);  // strict membership (type must match too)\narray_search(3, $a);      // the key of the first match, or false\narray_key_exists('k', $assoc); // true if the key exists (even if value is null)\n",[15,3144,3145,3165,3180,3199,3210,3221,3235,3239,3250,3265,3284,3299],{"__ignoreMap":88},[92,3146,3147,3149,3151,3153,3155,3157,3159,3161,3163],{"class":94,"line":95},[92,3148,321],{"class":119},[92,3150,126],{"class":98},[92,3152,347],{"class":119},[92,3154,68],{"class":102},[92,3156,195],{"class":119},[92,3158,354],{"class":102},[92,3160,195],{"class":119},[92,3162,1448],{"class":102},[92,3164,1034],{"class":119},[92,3166,3167,3170,3172,3174,3177],{"class":94,"line":106},[92,3168,3169],{"class":119},"$a[] ",[92,3171,126],{"class":98},[92,3173,1926],{"class":102},[92,3175,3176],{"class":119},";                 ",[92,3178,3179],{"class":134},"// append: [1, 2, 3, 4]\n",[92,3181,3182,3185,3188,3190,3192,3194,3196],{"class":94,"line":113},[92,3183,3184],{"class":102},"array_push",[92,3186,3187],{"class":119},"($a, ",[92,3189,1463],{"class":102},[92,3191,195],{"class":119},[92,3193,1235],{"class":102},[92,3195,599],{"class":119},[92,3197,3198],{"class":134},"// append several: [1, 2, 3, 4, 5, 6]\n",[92,3200,3201,3204,3207],{"class":94,"line":138},[92,3202,3203],{"class":102},"array_pop",[92,3205,3206],{"class":119},"($a);            ",[92,3208,3209],{"class":134},"// remove and return the last (6); O(1)\n",[92,3211,3212,3215,3218],{"class":94,"line":143},[92,3213,3214],{"class":102},"array_shift",[92,3216,3217],{"class":119},"($a);          ",[92,3219,3220],{"class":134},"// remove and return the first (1); O(n), reindexes\n",[92,3222,3223,3226,3228,3230,3232],{"class":94,"line":149},[92,3224,3225],{"class":102},"array_unshift",[92,3227,3187],{"class":119},[92,3229,554],{"class":102},[92,3231,599],{"class":119},[92,3233,3234],{"class":134},"// prepend 0; O(n)\n",[92,3236,3237],{"class":94,"line":155},[92,3238,110],{"emptyLinePlaceholder":109},[92,3240,3241,3244,3247],{"class":94,"line":161},[92,3242,3243],{"class":102},"count",[92,3245,3246],{"class":119},"($a);                ",[92,3248,3249],{"class":134},"// number of elements (sizeof is an alias)\n",[92,3251,3252,3255,3257,3259,3262],{"class":94,"line":166},[92,3253,3254],{"class":102},"in_array",[92,3256,120],{"class":119},[92,3258,1448],{"class":102},[92,3260,3261],{"class":119},", $a);          ",[92,3263,3264],{"class":134},"// true: value membership\n",[92,3266,3267,3269,3271,3274,3277,3279,3281],{"class":94,"line":187},[92,3268,3254],{"class":102},[92,3270,120],{"class":119},[92,3272,3273],{"class":171},"'3'",[92,3275,3276],{"class":119},", $a, ",[92,3278,474],{"class":102},[92,3280,800],{"class":119},[92,3282,3283],{"class":134},"// strict membership (type must match too)\n",[92,3285,3286,3289,3291,3293,3296],{"class":94,"line":217},[92,3287,3288],{"class":102},"array_search",[92,3290,120],{"class":119},[92,3292,1448],{"class":102},[92,3294,3295],{"class":119},", $a);      ",[92,3297,3298],{"class":134},"// the key of the first match, or false\n",[92,3300,3301,3303,3305,3307,3310],{"class":94,"line":712},[92,3302,1087],{"class":102},[92,3304,120],{"class":119},[92,3306,3004],{"class":171},[92,3308,3309],{"class":119},", $assoc); ",[92,3311,3312],{"class":134},"// true if the key exists (even if value is null)\n",[242,3314,3316],{"id":3315},"keys-values-and-transformation","Keys, values, and transformation",[11,3318,3319,3320,3323,3324,3327,3328,3331,3332,3335,3336,3338,3339,3342,3343,3345,3346,3348],{},"The workhorses for reshaping data are ",[15,3321,3322],{},"array_map"," (transform every element), ",[15,3325,3326],{},"array_filter"," (keep elements that pass a test), and ",[15,3329,3330],{},"array_reduce"," (fold to a single value), all of which return a ",[1511,3333,3334],{},"new"," array and leave the original untouched. Two behaviors to internalize: ",[15,3337,3326],{}," keeps the original keys (so wrap it in ",[15,3340,3341],{},"array_values()"," when you want a clean list), and ",[15,3344,3322],{}," with a ",[15,3347,390],{}," callback zips arrays together.",[83,3350,3352],{"className":85,"code":3351,"language":87,"meta":88,"style":88},"$nums = [5, 3, 8, 1];\n\narray_keys($assoc);                        // ['name', 'age']\narray_values($assoc);                      // ['Ada', 36]\narray_flip(['a' => 1, 'b' => 2]);          // [1 => 'a', 2 => 'b'] (swap keys/values)\narray_key_first($assoc);                   // 'name'\narray_key_last($assoc);                    // 'age'\n\narray_map(fn($n) => $n * 2, $nums);        // [10, 6, 16, 2]\narray_filter($nums, fn($n) => $n > 3);     // [0 => 5, 2 => 8]  (keeps original keys)\narray_values(array_filter($nums, fn($n) => $n > 3)); // [5, 8]  (reindexed)\narray_reduce($nums, fn($carry, $n) => $carry + $n, 0); // 17  (0 is the seed)\narray_walk($nums, function (&$v) { $v *= 10; }); // mutate in place: [50, 30, 80, 10]\n",[15,3353,3354,3380,3384,3395,3406,3432,3443,3454,3458,3480,3500,3524,3547],{"__ignoreMap":88},[92,3355,3356,3359,3361,3363,3365,3367,3369,3371,3374,3376,3378],{"class":94,"line":95},[92,3357,3358],{"class":119},"$nums ",[92,3360,126],{"class":98},[92,3362,347],{"class":119},[92,3364,1463],{"class":102},[92,3366,195],{"class":119},[92,3368,1448],{"class":102},[92,3370,195],{"class":119},[92,3372,3373],{"class":102},"8",[92,3375,195],{"class":119},[92,3377,68],{"class":102},[92,3379,1034],{"class":119},[92,3381,3382],{"class":94,"line":106},[92,3383,110],{"emptyLinePlaceholder":109},[92,3385,3386,3389,3392],{"class":94,"line":113},[92,3387,3388],{"class":102},"array_keys",[92,3390,3391],{"class":119},"($assoc);                        ",[92,3393,3394],{"class":134},"// ['name', 'age']\n",[92,3396,3397,3400,3403],{"class":94,"line":138},[92,3398,3399],{"class":102},"array_values",[92,3401,3402],{"class":119},"($assoc);                      ",[92,3404,3405],{"class":134},"// ['Ada', 36]\n",[92,3407,3408,3411,3413,3415,3417,3419,3421,3423,3425,3427,3429],{"class":94,"line":143},[92,3409,3410],{"class":102},"array_flip",[92,3412,486],{"class":119},[92,3414,1844],{"class":171},[92,3416,1019],{"class":98},[92,3418,1849],{"class":102},[92,3420,195],{"class":119},[92,3422,198],{"class":171},[92,3424,1019],{"class":98},[92,3426,1225],{"class":102},[92,3428,1064],{"class":119},[92,3430,3431],{"class":134},"// [1 => 'a', 2 => 'b'] (swap keys/values)\n",[92,3433,3434,3437,3440],{"class":94,"line":149},[92,3435,3436],{"class":102},"array_key_first",[92,3438,3439],{"class":119},"($assoc);                   ",[92,3441,3442],{"class":134},"// 'name'\n",[92,3444,3445,3448,3451],{"class":94,"line":155},[92,3446,3447],{"class":102},"array_key_last",[92,3449,3450],{"class":119},"($assoc);                    ",[92,3452,3453],{"class":134},"// 'age'\n",[92,3455,3456],{"class":94,"line":161},[92,3457,110],{"emptyLinePlaceholder":109},[92,3459,3460,3462,3464,3467,3470,3472,3474,3477],{"class":94,"line":166},[92,3461,3322],{"class":102},[92,3463,120],{"class":119},[92,3465,3466],{"class":98},"fn",[92,3468,3469],{"class":119},"($n) => $n ",[92,3471,1959],{"class":98},[92,3473,1225],{"class":102},[92,3475,3476],{"class":119},", $nums);        ",[92,3478,3479],{"class":134},"// [10, 6, 16, 2]\n",[92,3481,3482,3484,3487,3489,3491,3493,3495,3497],{"class":94,"line":187},[92,3483,3326],{"class":102},[92,3485,3486],{"class":119},"($nums, ",[92,3488,3466],{"class":98},[92,3490,3469],{"class":119},[92,3492,1599],{"class":98},[92,3494,856],{"class":102},[92,3496,599],{"class":119},[92,3498,3499],{"class":134},"// [0 => 5, 2 => 8]  (keeps original keys)\n",[92,3501,3502,3504,3506,3508,3510,3512,3514,3516,3518,3521],{"class":94,"line":217},[92,3503,3399],{"class":102},[92,3505,120],{"class":119},[92,3507,3326],{"class":102},[92,3509,3486],{"class":119},[92,3511,3466],{"class":98},[92,3513,3469],{"class":119},[92,3515,1599],{"class":98},[92,3517,856],{"class":102},[92,3519,3520],{"class":119},")); ",[92,3522,3523],{"class":134},"// [5, 8]  (reindexed)\n",[92,3525,3526,3528,3530,3532,3535,3537,3540,3542,3544],{"class":94,"line":712},[92,3527,3330],{"class":102},[92,3529,3486],{"class":119},[92,3531,3466],{"class":98},[92,3533,3534],{"class":119},"($carry, $n) => $carry ",[92,3536,1795],{"class":98},[92,3538,3539],{"class":119}," $n, ",[92,3541,554],{"class":102},[92,3543,653],{"class":119},[92,3545,3546],{"class":134},"// 17  (0 is the seed)\n",[92,3548,3549,3552,3554,3557,3560,3562,3565,3567,3569,3572],{"class":94,"line":730},[92,3550,3551],{"class":102},"array_walk",[92,3553,3486],{"class":119},[92,3555,3556],{"class":98},"function",[92,3558,3559],{"class":119}," (",[92,3561,1807],{"class":98},[92,3563,3564],{"class":119},"$v) { $v ",[92,3566,1188],{"class":98},[92,3568,1286],{"class":102},[92,3570,3571],{"class":119},"; }); ",[92,3573,3574],{"class":134},"// mutate in place: [50, 30, 80, 10]\n",[242,3576,3578],{"id":3577},"combining-slicing-and-set-operations","Combining, slicing, and set operations",[11,3580,3581,3582,3585,3586,3588,3589,3591,3592,3594],{},"Beyond transformation, a handful of functions cover merging, extracting sub-ranges, and set math. The one to be careful with is ",[15,3583,3584],{},"array_merge"," versus the ",[15,3587,1795],{}," operator: ",[15,3590,3584],{}," renumbers integer keys and lets the later array win on string keys, while ",[15,3593,1795],{}," keeps the first array's values and never renumbers.",[83,3596,3598],{"className":85,"code":3597,"language":87,"meta":88,"style":88},"array_merge([1, 2], [3, 4]);               // [1, 2, 3, 4] (integer keys renumbered)\narray_merge(['a' => 1], ['a' => 2]);       // ['a' => 2]   (later wins on string keys)\narray_combine(['a', 'b'], [1, 2]);         // ['a' => 1, 'b' => 2] (keys + values)\n\narray_slice([1, 2, 3, 4, 5], 1, 2);        // [2, 3]  (offset, length)\narray_splice($nums, 1, 2, ['x']);          // removes 2 from index 1, inserts 'x' (in place)\narray_chunk([1, 2, 3, 4, 5], 2);           // [[1, 2], [3, 4], [5]]\narray_column($nested, 'name');             // ['Ada', 'Linus'] (pluck one field from rows)\narray_column($nested, 'age', 'name');      // ['Ada' => 36, 'Linus' => 54] (key by field)\n\narray_unique([1, 1, 2, 3, 3]);             // [0 => 1, 2 => 2, 3 => 3]\narray_diff([1, 2, 3, 4], [2, 4]);          // [0 => 1, 2 => 3]  (in first, not second)\narray_intersect([1, 2, 3], [2, 3, 4]);     // [1 => 2, 2 => 3]  (in both)\narray_reverse([1, 2, 3]);                  // [3, 2, 1]\nrange(1, 5);                               // [1, 2, 3, 4, 5]\nrange('a', 'e');                           // ['a', 'b', 'c', 'd', 'e']\narray_fill(0, 3, 0);                       // [0, 0, 0]\narray_sum($nums);                          // sum of all values\narray_product([2, 3, 4]);                  // 24\nmax($nums); min($nums);                    // largest / smallest value\n",[15,3599,3600,3628,3653,3680,3684,3723,3745,3779,3794,3811,3815,3846,3880,3915,3938,3957,3976,3999,4010,4032],{"__ignoreMap":88},[92,3601,3602,3604,3606,3608,3610,3612,3615,3617,3619,3622,3625],{"class":94,"line":95},[92,3603,3584],{"class":102},[92,3605,486],{"class":119},[92,3607,68],{"class":102},[92,3609,195],{"class":119},[92,3611,354],{"class":102},[92,3613,3614],{"class":119},"], [",[92,3616,1448],{"class":102},[92,3618,195],{"class":119},[92,3620,3621],{"class":102},"4",[92,3623,3624],{"class":119},"]);               ",[92,3626,3627],{"class":134},"// [1, 2, 3, 4] (integer keys renumbered)\n",[92,3629,3630,3632,3634,3636,3638,3640,3642,3644,3646,3648,3650],{"class":94,"line":106},[92,3631,3584],{"class":102},[92,3633,486],{"class":119},[92,3635,1844],{"class":171},[92,3637,1019],{"class":98},[92,3639,1849],{"class":102},[92,3641,3614],{"class":119},[92,3643,1844],{"class":171},[92,3645,1019],{"class":98},[92,3647,1225],{"class":102},[92,3649,627],{"class":119},[92,3651,3652],{"class":134},"// ['a' => 2]   (later wins on string keys)\n",[92,3654,3655,3658,3660,3662,3664,3666,3668,3670,3672,3674,3677],{"class":94,"line":113},[92,3656,3657],{"class":102},"array_combine",[92,3659,486],{"class":119},[92,3661,1844],{"class":171},[92,3663,195],{"class":119},[92,3665,198],{"class":171},[92,3667,3614],{"class":119},[92,3669,68],{"class":102},[92,3671,195],{"class":119},[92,3673,354],{"class":102},[92,3675,3676],{"class":119},"]);         ",[92,3678,3679],{"class":134},"// ['a' => 1, 'b' => 2] (keys + values)\n",[92,3681,3682],{"class":94,"line":138},[92,3683,110],{"emptyLinePlaceholder":109},[92,3685,3686,3689,3691,3693,3695,3697,3699,3701,3703,3705,3707,3709,3712,3714,3716,3718,3720],{"class":94,"line":143},[92,3687,3688],{"class":102},"array_slice",[92,3690,486],{"class":119},[92,3692,68],{"class":102},[92,3694,195],{"class":119},[92,3696,354],{"class":102},[92,3698,195],{"class":119},[92,3700,1448],{"class":102},[92,3702,195],{"class":119},[92,3704,3621],{"class":102},[92,3706,195],{"class":119},[92,3708,1463],{"class":102},[92,3710,3711],{"class":119},"], ",[92,3713,68],{"class":102},[92,3715,195],{"class":119},[92,3717,354],{"class":102},[92,3719,433],{"class":119},[92,3721,3722],{"class":134},"// [2, 3]  (offset, length)\n",[92,3724,3725,3728,3730,3732,3734,3736,3738,3740,3742],{"class":94,"line":149},[92,3726,3727],{"class":102},"array_splice",[92,3729,3486],{"class":119},[92,3731,68],{"class":102},[92,3733,195],{"class":119},[92,3735,354],{"class":102},[92,3737,2708],{"class":119},[92,3739,772],{"class":171},[92,3741,1064],{"class":119},[92,3743,3744],{"class":134},"// removes 2 from index 1, inserts 'x' (in place)\n",[92,3746,3747,3750,3752,3754,3756,3758,3760,3762,3764,3766,3768,3770,3772,3774,3776],{"class":94,"line":155},[92,3748,3749],{"class":102},"array_chunk",[92,3751,486],{"class":119},[92,3753,68],{"class":102},[92,3755,195],{"class":119},[92,3757,354],{"class":102},[92,3759,195],{"class":119},[92,3761,1448],{"class":102},[92,3763,195],{"class":119},[92,3765,3621],{"class":102},[92,3767,195],{"class":119},[92,3769,1463],{"class":102},[92,3771,3711],{"class":119},[92,3773,354],{"class":102},[92,3775,2378],{"class":119},[92,3777,3778],{"class":134},"// [[1, 2], [3, 4], [5]]\n",[92,3780,3781,3784,3787,3789,3791],{"class":94,"line":161},[92,3782,3783],{"class":102},"array_column",[92,3785,3786],{"class":119},"($nested, ",[92,3788,1016],{"class":171},[92,3790,2461],{"class":119},[92,3792,3793],{"class":134},"// ['Ada', 'Linus'] (pluck one field from rows)\n",[92,3795,3796,3798,3800,3802,3804,3806,3808],{"class":94,"line":166},[92,3797,3783],{"class":102},[92,3799,3786],{"class":119},[92,3801,2974],{"class":171},[92,3803,195],{"class":119},[92,3805,1016],{"class":171},[92,3807,448],{"class":119},[92,3809,3810],{"class":134},"// ['Ada' => 36, 'Linus' => 54] (key by field)\n",[92,3812,3813],{"class":94,"line":187},[92,3814,110],{"emptyLinePlaceholder":109},[92,3816,3817,3820,3822,3824,3826,3828,3830,3832,3834,3836,3838,3840,3843],{"class":94,"line":217},[92,3818,3819],{"class":102},"array_unique",[92,3821,486],{"class":119},[92,3823,68],{"class":102},[92,3825,195],{"class":119},[92,3827,68],{"class":102},[92,3829,195],{"class":119},[92,3831,354],{"class":102},[92,3833,195],{"class":119},[92,3835,1448],{"class":102},[92,3837,195],{"class":119},[92,3839,1448],{"class":102},[92,3841,3842],{"class":119},"]);             ",[92,3844,3845],{"class":134},"// [0 => 1, 2 => 2, 3 => 3]\n",[92,3847,3848,3851,3853,3855,3857,3859,3861,3863,3865,3867,3869,3871,3873,3875,3877],{"class":94,"line":712},[92,3849,3850],{"class":102},"array_diff",[92,3852,486],{"class":119},[92,3854,68],{"class":102},[92,3856,195],{"class":119},[92,3858,354],{"class":102},[92,3860,195],{"class":119},[92,3862,1448],{"class":102},[92,3864,195],{"class":119},[92,3866,3621],{"class":102},[92,3868,3614],{"class":119},[92,3870,354],{"class":102},[92,3872,195],{"class":119},[92,3874,3621],{"class":102},[92,3876,1064],{"class":119},[92,3878,3879],{"class":134},"// [0 => 1, 2 => 3]  (in first, not second)\n",[92,3881,3882,3885,3887,3889,3891,3893,3895,3897,3899,3901,3903,3905,3907,3909,3912],{"class":94,"line":730},[92,3883,3884],{"class":102},"array_intersect",[92,3886,486],{"class":119},[92,3888,68],{"class":102},[92,3890,195],{"class":119},[92,3892,354],{"class":102},[92,3894,195],{"class":119},[92,3896,1448],{"class":102},[92,3898,3614],{"class":119},[92,3900,354],{"class":102},[92,3902,195],{"class":119},[92,3904,1448],{"class":102},[92,3906,195],{"class":119},[92,3908,3621],{"class":102},[92,3910,3911],{"class":119},"]);     ",[92,3913,3914],{"class":134},"// [1 => 2, 2 => 3]  (in both)\n",[92,3916,3917,3920,3922,3924,3926,3928,3930,3932,3935],{"class":94,"line":747},[92,3918,3919],{"class":102},"array_reverse",[92,3921,486],{"class":119},[92,3923,68],{"class":102},[92,3925,195],{"class":119},[92,3927,354],{"class":102},[92,3929,195],{"class":119},[92,3931,1448],{"class":102},[92,3933,3934],{"class":119},"]);                  ",[92,3936,3937],{"class":134},"// [3, 2, 1]\n",[92,3939,3940,3943,3945,3947,3949,3951,3954],{"class":94,"line":763},[92,3941,3942],{"class":102},"range",[92,3944,120],{"class":119},[92,3946,68],{"class":102},[92,3948,195],{"class":119},[92,3950,1463],{"class":102},[92,3952,3953],{"class":119},");                               ",[92,3955,3956],{"class":134},"// [1, 2, 3, 4, 5]\n",[92,3958,3959,3961,3963,3965,3967,3970,3973],{"class":94,"line":780},[92,3960,3942],{"class":102},[92,3962,120],{"class":119},[92,3964,1844],{"class":171},[92,3966,195],{"class":119},[92,3968,3969],{"class":171},"'e'",[92,3971,3972],{"class":119},");                           ",[92,3974,3975],{"class":134},"// ['a', 'b', 'c', 'd', 'e']\n",[92,3977,3978,3981,3983,3985,3987,3989,3991,3993,3996],{"class":94,"line":785},[92,3979,3980],{"class":102},"array_fill",[92,3982,120],{"class":119},[92,3984,554],{"class":102},[92,3986,195],{"class":119},[92,3988,1448],{"class":102},[92,3990,195],{"class":119},[92,3992,554],{"class":102},[92,3994,3995],{"class":119},");                       ",[92,3997,3998],{"class":134},"// [0, 0, 0]\n",[92,4000,4001,4004,4007],{"class":94,"line":2585},[92,4002,4003],{"class":102},"array_sum",[92,4005,4006],{"class":119},"($nums);                          ",[92,4008,4009],{"class":134},"// sum of all values\n",[92,4011,4012,4015,4017,4019,4021,4023,4025,4027,4029],{"class":94,"line":2605},[92,4013,4014],{"class":102},"array_product",[92,4016,486],{"class":119},[92,4018,354],{"class":102},[92,4020,195],{"class":119},[92,4022,1448],{"class":102},[92,4024,195],{"class":119},[92,4026,3621],{"class":102},[92,4028,3934],{"class":119},[92,4030,4031],{"class":134},"// 24\n",[92,4033,4034,4037,4040,4043,4046],{"class":94,"line":2634},[92,4035,4036],{"class":102},"max",[92,4038,4039],{"class":119},"($nums); ",[92,4041,4042],{"class":102},"min",[92,4044,4045],{"class":119},"($nums);                    ",[92,4047,4048],{"class":134},"// largest / smallest value\n",[242,4050,4052],{"id":4051},"sorting","Sorting",[11,4054,4055,4056,4059,4060,4063,4064,4066],{},"PHP has a family of sort functions rather than one, and they differ along three axes: sort by value or by key, ascending or descending, and whether they preserve the key-to-value association. Every one of them sorts the array ",[1511,4057,4058],{},"in place"," and returns a boolean (see the gotchas), so you keep using the same variable afterward. Use the ",[15,4061,4062],{},"u*"," variants when you need a custom comparator, which should return the result of ",[15,4065,1368],{}," (or any negative, zero, positive integer).",[4068,4069,4070,4089],"table",{},[4071,4072,4073],"thead",{},[4074,4075,4076,4080,4083,4086],"tr",{},[4077,4078,4079],"th",{},"Function",[4077,4081,4082],{},"Sorts by",[4077,4084,4085],{},"Direction",[4077,4087,4088],{},"Keeps key association",[4090,4091,4092,4113,4130,4147,4163,4176,4190],"tbody",{},[4074,4093,4094,4104,4107,4110],{},[4095,4096,4097,4100,4101],"td",{},[15,4098,4099],{},"sort"," / ",[15,4102,4103],{},"rsort",[4095,4105,4106],{},"value",[4095,4108,4109],{},"asc / desc",[4095,4111,4112],{},"no (reindexes to 0,1,2)",[4074,4114,4115,4123,4125,4127],{},[4095,4116,4117,4100,4120],{},[15,4118,4119],{},"asort",[15,4121,4122],{},"arsort",[4095,4124,4106],{},[4095,4126,4109],{},[4095,4128,4129],{},"yes",[4074,4131,4132,4140,4143,4145],{},[4095,4133,4134,4100,4137],{},[15,4135,4136],{},"ksort",[15,4138,4139],{},"krsort",[4095,4141,4142],{},"key",[4095,4144,4109],{},[4095,4146,4129],{},[4074,4148,4149,4154,4157,4160],{},[4095,4150,4151],{},[15,4152,4153],{},"usort",[4095,4155,4156],{},"value (custom)",[4095,4158,4159],{},"custom",[4095,4161,4162],{},"no",[4074,4164,4165,4170,4172,4174],{},[4095,4166,4167],{},[15,4168,4169],{},"uasort",[4095,4171,4156],{},[4095,4173,4159],{},[4095,4175,4129],{},[4074,4177,4178,4183,4186,4188],{},[4095,4179,4180],{},[15,4181,4182],{},"uksort",[4095,4184,4185],{},"key (custom)",[4095,4187,4159],{},[4095,4189,4129],{},[4074,4191,4192,4197,4200,4203],{},[4095,4193,4194],{},[15,4195,4196],{},"natsort",[4095,4198,4199],{},"value (natural order)",[4095,4201,4202],{},"asc",[4095,4204,4129],{},[83,4206,4208],{"className":85,"code":4207,"language":87,"meta":88,"style":88},"$n = [5, 3, 8, 1];\nsort($n);                                  // [1, 3, 5, 8]; returns true, sorts in place\nrsort($n);                                 // [8, 5, 3, 1]\n\n$scores = ['ada' => 90, 'lin' => 70, 'joy' => 85];\nasort($scores);                            // by value, keys kept: ['lin'=>70, 'joy'=>85, 'ada'=>90]\nksort($scores);                            // by key:               ['ada'=>90, 'joy'=>85, 'lin'=>70]\n\n// Sort an array of rows by a field with a custom comparator:\nusort($nested, fn($a, $b) => $a['age'] \u003C=> $b['age']);  // youngest first\nusort($nested, fn($a, $b) => $b['age'] \u003C=> $a['age']);  // oldest first (operands flipped)\n",[15,4209,4210,4235,4245,4255,4259,4298,4308,4317,4321,4326,4354],{"__ignoreMap":88},[92,4211,4212,4215,4217,4219,4221,4223,4225,4227,4229,4231,4233],{"class":94,"line":95},[92,4213,4214],{"class":119},"$n ",[92,4216,126],{"class":98},[92,4218,347],{"class":119},[92,4220,1463],{"class":102},[92,4222,195],{"class":119},[92,4224,1448],{"class":102},[92,4226,195],{"class":119},[92,4228,3373],{"class":102},[92,4230,195],{"class":119},[92,4232,68],{"class":102},[92,4234,1034],{"class":119},[92,4236,4237,4239,4242],{"class":94,"line":106},[92,4238,4099],{"class":102},[92,4240,4241],{"class":119},"($n);                                  ",[92,4243,4244],{"class":134},"// [1, 3, 5, 8]; returns true, sorts in place\n",[92,4246,4247,4249,4252],{"class":94,"line":113},[92,4248,4103],{"class":102},[92,4250,4251],{"class":119},"($n);                                 ",[92,4253,4254],{"class":134},"// [8, 5, 3, 1]\n",[92,4256,4257],{"class":94,"line":138},[92,4258,110],{"emptyLinePlaceholder":109},[92,4260,4261,4264,4266,4268,4271,4273,4276,4278,4281,4283,4286,4288,4291,4293,4296],{"class":94,"line":143},[92,4262,4263],{"class":119},"$scores ",[92,4265,126],{"class":98},[92,4267,347],{"class":119},[92,4269,4270],{"class":171},"'ada'",[92,4272,1019],{"class":98},[92,4274,4275],{"class":102}," 90",[92,4277,195],{"class":119},[92,4279,4280],{"class":171},"'lin'",[92,4282,1019],{"class":98},[92,4284,4285],{"class":102}," 70",[92,4287,195],{"class":119},[92,4289,4290],{"class":171},"'joy'",[92,4292,1019],{"class":98},[92,4294,4295],{"class":102}," 85",[92,4297,1034],{"class":119},[92,4299,4300,4302,4305],{"class":94,"line":149},[92,4301,4119],{"class":102},[92,4303,4304],{"class":119},"($scores);                            ",[92,4306,4307],{"class":134},"// by value, keys kept: ['lin'=>70, 'joy'=>85, 'ada'=>90]\n",[92,4309,4310,4312,4314],{"class":94,"line":155},[92,4311,4136],{"class":102},[92,4313,4304],{"class":119},[92,4315,4316],{"class":134},"// by key:               ['ada'=>90, 'joy'=>85, 'lin'=>70]\n",[92,4318,4319],{"class":94,"line":161},[92,4320,110],{"emptyLinePlaceholder":109},[92,4322,4323],{"class":94,"line":166},[92,4324,4325],{"class":134},"// Sort an array of rows by a field with a custom comparator:\n",[92,4327,4328,4330,4332,4334,4337,4339,4341,4343,4346,4348,4351],{"class":94,"line":187},[92,4329,4153],{"class":102},[92,4331,3786],{"class":119},[92,4333,3466],{"class":98},[92,4335,4336],{"class":119},"($a, $b) => $a[",[92,4338,2974],{"class":171},[92,4340,1751],{"class":119},[92,4342,1368],{"class":98},[92,4344,4345],{"class":119}," $b[",[92,4347,2974],{"class":171},[92,4349,4350],{"class":119},"]);  ",[92,4352,4353],{"class":134},"// youngest first\n",[92,4355,4356,4358,4360,4362,4365,4367,4369,4371,4374,4376,4378],{"class":94,"line":217},[92,4357,4153],{"class":102},[92,4359,3786],{"class":119},[92,4361,3466],{"class":98},[92,4363,4364],{"class":119},"($a, $b) => $b[",[92,4366,2974],{"class":171},[92,4368,1751],{"class":119},[92,4370,1368],{"class":98},[92,4372,4373],{"class":119}," $a[",[92,4375,2974],{"class":171},[92,4377,4350],{"class":119},[92,4379,4380],{"class":134},"// oldest first (operands flipped)\n",[242,4382,4384],{"id":4383},"destructuring-and-iteration","Destructuring and iteration",[11,4386,4387,4388,4391,4392,4395,4396,4399,4400,4402],{},"You can pull an array apart by position or by key with the ",[15,4389,4390],{},"[...]"," destructuring syntax, and skip elements by leaving a hole. Iteration is almost always ",[15,4393,4394],{},"foreach",", which can hand you just the value, or the key and value together, or a ",[1511,4397,4398],{},"reference"," to each element (with ",[15,4401,1807],{},") when you want to modify the array as you loop.",[83,4404,4406],{"className":85,"code":4405,"language":87,"meta":88,"style":88},"[$first, $second] = [10, 20];              // by position\n['name' => $name] = $assoc;                // by key\n[, $onlySecond] = [1, 2];                  // skip the first element\n[$a, $b] = [$b, $a];                       // swap without a temp variable\n\nforeach ($nums as $value) { /* value only */ }\nforeach ($assoc as $key => $value) { /* key and value */ }\nforeach ($nums as &$value) { $value *= 2; } // modify in place via reference\nunset($value);                              // ALWAYS unset after a reference loop (see gotchas)\n",[15,4407,4408,4431,4450,4471,4484,4488,4507,4529,4552],{"__ignoreMap":88},[92,4409,4410,4413,4415,4417,4420,4422,4425,4428],{"class":94,"line":95},[92,4411,4412],{"class":119},"[$first, $second] ",[92,4414,126],{"class":98},[92,4416,347],{"class":119},[92,4418,4419],{"class":102},"10",[92,4421,195],{"class":119},[92,4423,4424],{"class":102},"20",[92,4426,4427],{"class":119},"];              ",[92,4429,4430],{"class":134},"// by position\n",[92,4432,4433,4435,4437,4439,4442,4444,4447],{"class":94,"line":106},[92,4434,1841],{"class":119},[92,4436,1016],{"class":171},[92,4438,1019],{"class":98},[92,4440,4441],{"class":119}," $name] ",[92,4443,126],{"class":98},[92,4445,4446],{"class":119}," $assoc;                ",[92,4448,4449],{"class":134},"// by key\n",[92,4451,4452,4455,4457,4459,4461,4463,4465,4468],{"class":94,"line":113},[92,4453,4454],{"class":119},"[, $onlySecond] ",[92,4456,126],{"class":98},[92,4458,347],{"class":119},[92,4460,68],{"class":102},[92,4462,195],{"class":119},[92,4464,354],{"class":102},[92,4466,4467],{"class":119},"];                  ",[92,4469,4470],{"class":134},"// skip the first element\n",[92,4472,4473,4476,4478,4481],{"class":94,"line":138},[92,4474,4475],{"class":119},"[$a, $b] ",[92,4477,126],{"class":98},[92,4479,4480],{"class":119}," [$b, $a];                       ",[92,4482,4483],{"class":134},"// swap without a temp variable\n",[92,4485,4486],{"class":94,"line":143},[92,4487,110],{"emptyLinePlaceholder":109},[92,4489,4490,4492,4495,4498,4501,4504],{"class":94,"line":149},[92,4491,4394],{"class":98},[92,4493,4494],{"class":119}," ($nums ",[92,4496,4497],{"class":98},"as",[92,4499,4500],{"class":119}," $value) { ",[92,4502,4503],{"class":134},"/* value only */",[92,4505,4506],{"class":119}," }\n",[92,4508,4509,4511,4514,4516,4519,4522,4524,4527],{"class":94,"line":155},[92,4510,4394],{"class":98},[92,4512,4513],{"class":119}," ($assoc ",[92,4515,4497],{"class":98},[92,4517,4518],{"class":119}," $key ",[92,4520,4521],{"class":98},"=>",[92,4523,4500],{"class":119},[92,4525,4526],{"class":134},"/* key and value */",[92,4528,4506],{"class":119},[92,4530,4531,4533,4535,4537,4539,4542,4544,4546,4549],{"class":94,"line":161},[92,4532,4394],{"class":98},[92,4534,4494],{"class":119},[92,4536,4497],{"class":98},[92,4538,1895],{"class":98},[92,4540,4541],{"class":119},"$value) { $value ",[92,4543,1188],{"class":98},[92,4545,1225],{"class":102},[92,4547,4548],{"class":119},"; } ",[92,4550,4551],{"class":134},"// modify in place via reference\n",[92,4553,4554,4556,4559],{"class":94,"line":166},[92,4555,1131],{"class":102},[92,4557,4558],{"class":119},"($value);                              ",[92,4560,4561],{"class":134},"// ALWAYS unset after a reference loop (see gotchas)\n",[11,4563,4564,4565,4568,4569,4571,4572,4575],{},"In practice, associative arrays are your hash map and your set in almost every coding round: use ",[15,4566,4567],{},"isset($map[$key])"," for O(1) membership and use the array keys themselves as a set of unique values. The one performance caveat is that ",[15,4570,3214],{}," is O(n) because it renumbers keys, so if you build a BFS queue on a large input, reach for ",[15,4573,4574],{},"SplQueue"," (covered later) instead.",[39,4577,4579],{"id":4578},"control-flow","Control Flow",[242,4581,4583],{"id":4582},"conditionals","Conditionals",[11,4585,4586,4100,4589,4100,4592,4595,4596,4599,4600,4603,4604,4607,4608,4611,4612,4615,4616,4618,4619,4621,4622,4625,4626,81],{},[15,4587,4588],{},"if",[15,4590,4591],{},"elseif",[15,4593,4594],{},"else"," work as expected, and PHP also offers an alternative colon syntax (",[15,4597,4598],{},"if (...):"," ... ",[15,4601,4602],{},"endif;",") that is common inside HTML templates. For choosing among many discrete values, ",[15,4605,4606],{},"switch"," has been around forever but uses ",[1511,4609,4610],{},"loose"," comparison and requires an explicit ",[15,4613,4614],{},"break"," in every case to avoid fall-through, both of which cause bugs. The modern replacement is ",[15,4617,17],{}," (PHP 8.0), which compares with strict equality, returns a value, needs no ",[15,4620,4614],{},", and throws ",[15,4623,4624],{},"UnhandledMatchError"," if nothing matches and there is no ",[15,4627,4628],{},"default",[83,4630,4632],{"className":85,"code":4631,"language":87,"meta":88,"style":88},"if ($n > 0) {\n    $sign = 'positive';\n} elseif ($n \u003C 0) {\n    $sign = 'negative';\n} else {\n    $sign = 'zero';\n}\n\n// match: strict comparison, returns a value, no fall-through\n$label = match ($status) {\n    200, 201, 204 => 'success',   // several values can share one arm\n    404           => 'not found',\n    500           => 'server error',\n    default       => 'unknown',\n};\n\n// switch: loose comparison, needs break, falls through without it\nswitch ($status) {\n    case 200:\n    case 201:\n        $label = 'success';\n        break;\n    default:\n        $label = 'unknown';\n}\n",[15,4633,4634,4648,4660,4676,4687,4696,4707,4712,4716,4721,4734,4759,4773,4785,4798,4803,4807,4812,4818,4829,4838,4849,4856,4862,4872],{"__ignoreMap":88},[92,4635,4636,4638,4641,4643,4645],{"class":94,"line":95},[92,4637,4588],{"class":98},[92,4639,4640],{"class":119}," ($n ",[92,4642,1599],{"class":98},[92,4644,331],{"class":102},[92,4646,4647],{"class":119},") {\n",[92,4649,4650,4653,4655,4658],{"class":94,"line":106},[92,4651,4652],{"class":119},"    $sign ",[92,4654,126],{"class":98},[92,4656,4657],{"class":171}," 'positive'",[92,4659,229],{"class":119},[92,4661,4662,4665,4667,4669,4672,4674],{"class":94,"line":113},[92,4663,4664],{"class":119},"} ",[92,4666,4591],{"class":98},[92,4668,4640],{"class":119},[92,4670,4671],{"class":98},"\u003C",[92,4673,331],{"class":102},[92,4675,4647],{"class":119},[92,4677,4678,4680,4682,4685],{"class":94,"line":138},[92,4679,4652],{"class":119},[92,4681,126],{"class":98},[92,4683,4684],{"class":171}," 'negative'",[92,4686,229],{"class":119},[92,4688,4689,4691,4693],{"class":94,"line":143},[92,4690,4664],{"class":119},[92,4692,4594],{"class":98},[92,4694,4695],{"class":119}," {\n",[92,4697,4698,4700,4702,4705],{"class":94,"line":149},[92,4699,4652],{"class":119},[92,4701,126],{"class":98},[92,4703,4704],{"class":171}," 'zero'",[92,4706,229],{"class":119},[92,4708,4709],{"class":94,"line":155},[92,4710,4711],{"class":119},"}\n",[92,4713,4714],{"class":94,"line":161},[92,4715,110],{"emptyLinePlaceholder":109},[92,4717,4718],{"class":94,"line":166},[92,4719,4720],{"class":134},"// match: strict comparison, returns a value, no fall-through\n",[92,4722,4723,4726,4728,4731],{"class":94,"line":187},[92,4724,4725],{"class":119},"$label ",[92,4727,126],{"class":98},[92,4729,4730],{"class":98}," match",[92,4732,4733],{"class":119}," ($status) {\n",[92,4735,4736,4739,4741,4744,4746,4749,4751,4754,4756],{"class":94,"line":217},[92,4737,4738],{"class":102},"    200",[92,4740,195],{"class":119},[92,4742,4743],{"class":102},"201",[92,4745,195],{"class":119},[92,4747,4748],{"class":102},"204",[92,4750,1019],{"class":98},[92,4752,4753],{"class":171}," 'success'",[92,4755,3048],{"class":119},[92,4757,4758],{"class":134},"// several values can share one arm\n",[92,4760,4761,4764,4767,4770],{"class":94,"line":712},[92,4762,4763],{"class":102},"    404",[92,4765,4766],{"class":98},"           =>",[92,4768,4769],{"class":171}," 'not found'",[92,4771,4772],{"class":119},",\n",[92,4774,4775,4778,4780,4783],{"class":94,"line":730},[92,4776,4777],{"class":102},"    500",[92,4779,4766],{"class":98},[92,4781,4782],{"class":171}," 'server error'",[92,4784,4772],{"class":119},[92,4786,4787,4790,4793,4796],{"class":94,"line":747},[92,4788,4789],{"class":98},"    default",[92,4791,4792],{"class":98},"       =>",[92,4794,4795],{"class":171}," 'unknown'",[92,4797,4772],{"class":119},[92,4799,4800],{"class":94,"line":763},[92,4801,4802],{"class":119},"};\n",[92,4804,4805],{"class":94,"line":780},[92,4806,110],{"emptyLinePlaceholder":109},[92,4808,4809],{"class":94,"line":785},[92,4810,4811],{"class":134},"// switch: loose comparison, needs break, falls through without it\n",[92,4813,4814,4816],{"class":94,"line":2585},[92,4815,4606],{"class":98},[92,4817,4733],{"class":119},[92,4819,4820,4823,4826],{"class":94,"line":2605},[92,4821,4822],{"class":98},"    case",[92,4824,4825],{"class":102}," 200",[92,4827,4828],{"class":119},":\n",[92,4830,4831,4833,4836],{"class":94,"line":2634},[92,4832,4822],{"class":98},[92,4834,4835],{"class":102}," 201",[92,4837,4828],{"class":119},[92,4839,4840,4843,4845,4847],{"class":94,"line":2651},[92,4841,4842],{"class":119},"        $label ",[92,4844,126],{"class":98},[92,4846,4753],{"class":171},[92,4848,229],{"class":119},[92,4850,4851,4854],{"class":94,"line":2671},[92,4852,4853],{"class":98},"        break",[92,4855,229],{"class":119},[92,4857,4858,4860],{"class":94,"line":2676},[92,4859,4789],{"class":98},[92,4861,4828],{"class":119},[92,4863,4864,4866,4868,4870],{"class":94,"line":2697},[92,4865,4842],{"class":119},[92,4867,126],{"class":98},[92,4869,4795],{"class":171},[92,4871,229],{"class":119},[92,4873,4874],{"class":94,"line":2726},[92,4875,4711],{"class":119},[242,4877,4879],{"id":4878},"loops-and-loop-control","Loops and loop control",[11,4881,4882,4883,4885,4886,4888,4889,4892,4893,4896],{},"PHP has the standard four loops, and ",[15,4884,4394],{}," is the one you use for anything array-shaped. ",[15,4887,4614],{}," exits the loop and ",[15,4890,4891],{},"continue"," skips to the next iteration, and both accept an integer level so ",[15,4894,4895],{},"break 2"," escapes two nested loops at once, which is genuinely useful in grid and matrix problems.",[83,4898,4900],{"className":85,"code":4899,"language":87,"meta":88,"style":88},"for ($i = 0; $i \u003C 5; $i++) { /* ... */ }\nforeach ($items as $item)   { /* ... */ }\n\n$i = 0;\nwhile ($i \u003C 5) { $i++; }\ndo { $i--; } while ($i > 0);   // body runs at least once\n\nforeach ($grid as $row) {\n    foreach ($row as $cell) {\n        if ($cell === null) {\n            continue 2;   // skip to the next ROW, not the next cell\n        }\n        if ($cell === 'X') {\n            break 2;      // exit both loops entirely\n        }\n    }\n}\n",[15,4901,4902,4935,4951,4955,4966,4985,5011,5015,5027,5040,5054,5066,5071,5084,5096,5100,5105],{"__ignoreMap":88},[92,4903,4904,4907,4910,4912,4914,4917,4919,4921,4924,4927,4930,4933],{"class":94,"line":95},[92,4905,4906],{"class":98},"for",[92,4908,4909],{"class":119}," ($i ",[92,4911,126],{"class":98},[92,4913,331],{"class":102},[92,4915,4916],{"class":119},"; $i ",[92,4918,4671],{"class":98},[92,4920,1315],{"class":102},[92,4922,4923],{"class":119},"; $i",[92,4925,4926],{"class":98},"++",[92,4928,4929],{"class":119},") { ",[92,4931,4932],{"class":134},"/* ... */",[92,4934,4506],{"class":119},[92,4936,4937,4939,4942,4944,4947,4949],{"class":94,"line":106},[92,4938,4394],{"class":98},[92,4940,4941],{"class":119}," ($items ",[92,4943,4497],{"class":98},[92,4945,4946],{"class":119}," $item)   { ",[92,4948,4932],{"class":134},[92,4950,4506],{"class":119},[92,4952,4953],{"class":94,"line":113},[92,4954,110],{"emptyLinePlaceholder":109},[92,4956,4957,4960,4962,4964],{"class":94,"line":138},[92,4958,4959],{"class":119},"$i ",[92,4961,126],{"class":98},[92,4963,331],{"class":102},[92,4965,229],{"class":119},[92,4967,4968,4971,4973,4975,4977,4980,4982],{"class":94,"line":143},[92,4969,4970],{"class":98},"while",[92,4972,4909],{"class":119},[92,4974,4671],{"class":98},[92,4976,1315],{"class":102},[92,4978,4979],{"class":119},") { $i",[92,4981,4926],{"class":98},[92,4983,4984],{"class":119},"; }\n",[92,4986,4987,4990,4993,4996,4998,5000,5002,5004,5006,5008],{"class":94,"line":149},[92,4988,4989],{"class":98},"do",[92,4991,4992],{"class":119}," { $i",[92,4994,4995],{"class":98},"--",[92,4997,4548],{"class":119},[92,4999,4970],{"class":98},[92,5001,4909],{"class":119},[92,5003,1599],{"class":98},[92,5005,331],{"class":102},[92,5007,131],{"class":119},[92,5009,5010],{"class":134},"// body runs at least once\n",[92,5012,5013],{"class":94,"line":155},[92,5014,110],{"emptyLinePlaceholder":109},[92,5016,5017,5019,5022,5024],{"class":94,"line":161},[92,5018,4394],{"class":98},[92,5020,5021],{"class":119}," ($grid ",[92,5023,4497],{"class":98},[92,5025,5026],{"class":119}," $row) {\n",[92,5028,5029,5032,5035,5037],{"class":94,"line":166},[92,5030,5031],{"class":98},"    foreach",[92,5033,5034],{"class":119}," ($row ",[92,5036,4497],{"class":98},[92,5038,5039],{"class":119}," $cell) {\n",[92,5041,5042,5045,5048,5050,5052],{"class":94,"line":187},[92,5043,5044],{"class":98},"        if",[92,5046,5047],{"class":119}," ($cell ",[92,5049,1352],{"class":98},[92,5051,1031],{"class":102},[92,5053,4647],{"class":119},[92,5055,5056,5059,5061,5063],{"class":94,"line":217},[92,5057,5058],{"class":98},"            continue",[92,5060,1225],{"class":102},[92,5062,309],{"class":119},[92,5064,5065],{"class":134},"// skip to the next ROW, not the next cell\n",[92,5067,5068],{"class":94,"line":712},[92,5069,5070],{"class":119},"        }\n",[92,5072,5073,5075,5077,5079,5082],{"class":94,"line":730},[92,5074,5044],{"class":98},[92,5076,5047],{"class":119},[92,5078,1352],{"class":98},[92,5080,5081],{"class":171}," 'X'",[92,5083,4647],{"class":119},[92,5085,5086,5089,5091,5093],{"class":94,"line":747},[92,5087,5088],{"class":98},"            break",[92,5090,1225],{"class":102},[92,5092,946],{"class":119},[92,5094,5095],{"class":134},"// exit both loops entirely\n",[92,5097,5098],{"class":94,"line":763},[92,5099,5070],{"class":119},[92,5101,5102],{"class":94,"line":780},[92,5103,5104],{"class":119},"    }\n",[92,5106,5107],{"class":94,"line":785},[92,5108,4711],{"class":119},[11,5110,5111,5112,5114,5115,5117,5118,5121],{},"Default to ",[15,5113,17],{}," in new code and fall back to ",[15,5116,4606],{}," only when you actually want fall-through, because reintroducing loose comparison is exactly how a ",[15,5119,5120],{},"match ($n)"," against a string sneaks a bug past you.",[39,5123,5125],{"id":5124},"functions","Functions",[242,5127,5129],{"id":5128},"definitions-parameters-and-return-types","Definitions, parameters, and return types",[11,5131,5132,5133,5136,5137,5140,5141,195,5144,394,5147,81],{},"A function declares typed parameters and a return type, and a parameter becomes optional by giving it a default value, which must be a constant expression. Named arguments (PHP 8.0) let a caller pass values by parameter name and skip earlier optional ones, which makes long signatures readable. Return types include the usual scalars plus ",[15,5134,5135],{},"void"," (returns nothing), ",[15,5138,5139],{},"never"," (never returns, always throws or exits), ",[15,5142,5143],{},"self",[15,5145,5146],{},"static",[15,5148,5149],{},"mixed",[83,5151,5153],{"className":85,"code":5152,"language":87,"meta":88,"style":88},"function greet(string $name, string $greeting = 'Hello'): string {\n    return \"$greeting, $name\";\n}\n\ngreet('Ada');                          // 'Hello, Ada'\ngreet('Ada', 'Hi');                    // 'Hi, Ada'      (positional)\ngreet(greeting: 'Hey', name: 'Ada');   // 'Hey, Ada'     (named, any order)\n\nfunction log(string $msg): void {      // void: returns nothing\n    echo $msg, PHP_EOL;\n}\n",[15,5154,5155,5191,5210,5214,5218,5234,5252,5281,5285,5310,5322],{"__ignoreMap":88},[92,5156,5157,5159,5163,5165,5167,5170,5172,5175,5177,5180,5183,5186,5189],{"class":94,"line":95},[92,5158,3556],{"class":98},[92,5160,5162],{"class":5161},"svObZ"," greet",[92,5164,120],{"class":119},[92,5166,376],{"class":98},[92,5168,5169],{"class":119}," $name, ",[92,5171,376],{"class":98},[92,5173,5174],{"class":119}," $greeting ",[92,5176,126],{"class":98},[92,5178,5179],{"class":171}," 'Hello'",[92,5181,5182],{"class":119},")",[92,5184,5185],{"class":98},":",[92,5187,5188],{"class":98}," string",[92,5190,4695],{"class":119},[92,5192,5193,5196,5199,5202,5204,5206,5208],{"class":94,"line":106},[92,5194,5195],{"class":98},"    return",[92,5197,5198],{"class":171}," \"",[92,5200,5201],{"class":119},"$greeting",[92,5203,195],{"class":171},[92,5205,2042],{"class":119},[92,5207,178],{"class":171},[92,5209,229],{"class":119},[92,5211,5212],{"class":94,"line":113},[92,5213,4711],{"class":119},[92,5215,5216],{"class":94,"line":138},[92,5217,110],{"emptyLinePlaceholder":109},[92,5219,5220,5223,5225,5228,5231],{"class":94,"line":143},[92,5221,5222],{"class":5161},"greet",[92,5224,120],{"class":119},[92,5226,5227],{"class":171},"'Ada'",[92,5229,5230],{"class":119},");                          ",[92,5232,5233],{"class":134},"// 'Hello, Ada'\n",[92,5235,5236,5238,5240,5242,5244,5247,5249],{"class":94,"line":149},[92,5237,5222],{"class":5161},[92,5239,120],{"class":119},[92,5241,5227],{"class":171},[92,5243,195],{"class":119},[92,5245,5246],{"class":171},"'Hi'",[92,5248,2645],{"class":119},[92,5250,5251],{"class":134},"// 'Hi, Ada'      (positional)\n",[92,5253,5254,5256,5258,5261,5264,5267,5269,5272,5274,5276,5278],{"class":94,"line":155},[92,5255,5222],{"class":5161},[92,5257,120],{"class":119},[92,5259,5260],{"class":5161},"greeting",[92,5262,5263],{"class":119},": ",[92,5265,5266],{"class":171},"'Hey'",[92,5268,195],{"class":119},[92,5270,5271],{"class":5161},"name",[92,5273,5263],{"class":119},[92,5275,5227],{"class":171},[92,5277,131],{"class":119},[92,5279,5280],{"class":134},"// 'Hey, Ada'     (named, any order)\n",[92,5282,5283],{"class":94,"line":161},[92,5284,110],{"emptyLinePlaceholder":109},[92,5286,5287,5289,5292,5294,5296,5299,5301,5304,5307],{"class":94,"line":166},[92,5288,3556],{"class":98},[92,5290,5291],{"class":5161}," log",[92,5293,120],{"class":119},[92,5295,376],{"class":98},[92,5297,5298],{"class":119}," $msg)",[92,5300,5185],{"class":98},[92,5302,5303],{"class":98}," void",[92,5305,5306],{"class":119}," {      ",[92,5308,5309],{"class":134},"// void: returns nothing\n",[92,5311,5312,5315,5318,5320],{"class":94,"line":187},[92,5313,5314],{"class":102},"    echo",[92,5316,5317],{"class":119}," $msg, ",[92,5319,208],{"class":102},[92,5321,229],{"class":119},[92,5323,5324],{"class":94,"line":217},[92,5325,4711],{"class":119},[242,5327,5329],{"id":5328},"variadics-and-the-spread-operator","Variadics and the spread operator",[11,5331,5332,5333,5336,5337,5339,5340,5343],{},"A variadic parameter, written with ",[15,5334,5335],{},"...",", collects any number of trailing arguments into an array, and the same ",[15,5338,5335],{}," \"spreads\" an array back into individual arguments at a call site. This replaces the old ",[15,5341,5342],{},"func_get_args()"," approach and works with type hints.",[83,5345,5347],{"className":85,"code":5346,"language":87,"meta":88,"style":88},"function sum(int ...$nums): int {      // collect all args into $nums\n    return array_sum($nums);\n}\nsum(1, 2, 3);          // 6\nsum(...[4, 5, 6]);     // 15  (spread an array into the argument list)\n\n$parts = ['2026', '08', '25'];\nsprintf('%s-%s-%s', ...$parts);        // '2026-08-25'\n",[15,5348,5349,5376,5386,5390,5412,5437,5441,5465],{"__ignoreMap":88},[92,5350,5351,5353,5356,5358,5360,5363,5366,5368,5371,5373],{"class":94,"line":95},[92,5352,3556],{"class":98},[92,5354,5355],{"class":5161}," sum",[92,5357,120],{"class":119},[92,5359,370],{"class":98},[92,5361,5362],{"class":98}," ...",[92,5364,5365],{"class":119},"$nums)",[92,5367,5185],{"class":98},[92,5369,5370],{"class":98}," int",[92,5372,5306],{"class":119},[92,5374,5375],{"class":134},"// collect all args into $nums\n",[92,5377,5378,5380,5383],{"class":94,"line":106},[92,5379,5195],{"class":98},[92,5381,5382],{"class":102}," array_sum",[92,5384,5385],{"class":119},"($nums);\n",[92,5387,5388],{"class":94,"line":113},[92,5389,4711],{"class":119},[92,5391,5392,5395,5397,5399,5401,5403,5405,5407,5409],{"class":94,"line":138},[92,5393,5394],{"class":5161},"sum",[92,5396,120],{"class":119},[92,5398,68],{"class":102},[92,5400,195],{"class":119},[92,5402,354],{"class":102},[92,5404,195],{"class":119},[92,5406,1448],{"class":102},[92,5408,571],{"class":119},[92,5410,5411],{"class":134},"// 6\n",[92,5413,5414,5416,5418,5420,5422,5424,5426,5428,5430,5432,5434],{"class":94,"line":143},[92,5415,5394],{"class":5161},[92,5417,120],{"class":119},[92,5419,5335],{"class":98},[92,5421,1841],{"class":119},[92,5423,3621],{"class":102},[92,5425,195],{"class":119},[92,5427,1463],{"class":102},[92,5429,195],{"class":119},[92,5431,1235],{"class":102},[92,5433,3911],{"class":119},[92,5435,5436],{"class":134},"// 15  (spread an array into the argument list)\n",[92,5438,5439],{"class":94,"line":149},[92,5440,110],{"emptyLinePlaceholder":109},[92,5442,5443,5446,5448,5450,5453,5455,5458,5460,5463],{"class":94,"line":155},[92,5444,5445],{"class":119},"$parts ",[92,5447,126],{"class":98},[92,5449,347],{"class":119},[92,5451,5452],{"class":171},"'2026'",[92,5454,195],{"class":119},[92,5456,5457],{"class":171},"'08'",[92,5459,195],{"class":119},[92,5461,5462],{"class":171},"'25'",[92,5464,1034],{"class":119},[92,5466,5467,5469,5471,5474,5476,5478,5481],{"class":94,"line":161},[92,5468,2729],{"class":102},[92,5470,120],{"class":119},[92,5472,5473],{"class":171},"'%s-%s-%s'",[92,5475,195],{"class":119},[92,5477,5335],{"class":98},[92,5479,5480],{"class":119},"$parts);        ",[92,5482,5483],{"class":134},"// '2026-08-25'\n",[242,5485,5487],{"id":5486},"pass-by-value-versus-reference","Pass by value versus reference",[11,5489,5490,5491,5493,5494,834,5497,5499],{},"Arguments pass by value by default, so a function receives a copy and cannot change the caller's variable. To let a function modify the original, declare the parameter with ",[15,5492,1807],{},", which passes it by reference. This is the mechanism behind functions like ",[15,5495,5496],{},"sort()",[15,5498,3125],{}," that mutate their argument in place.",[83,5501,5503],{"className":85,"code":5502,"language":87,"meta":88,"style":88},"function addOne(int $x): void   { $x++; }        // by value: no outside effect\nfunction bumpUp(int &$x): void  { $x++; }        // by reference: mutates the caller\n\n$n = 5;\naddOne($n);   // $n is still 5\nbumpUp($n);   // $n is now 6\n",[15,5504,5505,5534,5564,5568,5578,5589],{"__ignoreMap":88},[92,5506,5507,5509,5512,5514,5516,5519,5521,5523,5526,5528,5531],{"class":94,"line":95},[92,5508,3556],{"class":98},[92,5510,5511],{"class":5161}," addOne",[92,5513,120],{"class":119},[92,5515,370],{"class":98},[92,5517,5518],{"class":119}," $x)",[92,5520,5185],{"class":98},[92,5522,5303],{"class":98},[92,5524,5525],{"class":119},"   { $x",[92,5527,4926],{"class":98},[92,5529,5530],{"class":119},"; }        ",[92,5532,5533],{"class":134},"// by value: no outside effect\n",[92,5535,5536,5538,5541,5543,5545,5547,5550,5552,5554,5557,5559,5561],{"class":94,"line":106},[92,5537,3556],{"class":98},[92,5539,5540],{"class":5161}," bumpUp",[92,5542,120],{"class":119},[92,5544,370],{"class":98},[92,5546,1895],{"class":98},[92,5548,5549],{"class":119},"$x)",[92,5551,5185],{"class":98},[92,5553,5303],{"class":98},[92,5555,5556],{"class":119},"  { $x",[92,5558,4926],{"class":98},[92,5560,5530],{"class":119},[92,5562,5563],{"class":134},"// by reference: mutates the caller\n",[92,5565,5566],{"class":94,"line":113},[92,5567,110],{"emptyLinePlaceholder":109},[92,5569,5570,5572,5574,5576],{"class":94,"line":138},[92,5571,4214],{"class":119},[92,5573,126],{"class":98},[92,5575,1315],{"class":102},[92,5577,229],{"class":119},[92,5579,5580,5583,5586],{"class":94,"line":143},[92,5581,5582],{"class":5161},"addOne",[92,5584,5585],{"class":119},"($n);   ",[92,5587,5588],{"class":134},"// $n is still 5\n",[92,5590,5591,5594,5596],{"class":94,"line":149},[92,5592,5593],{"class":5161},"bumpUp",[92,5595,5585],{"class":119},[92,5597,5598],{"class":134},"// $n is now 6\n",[242,5600,5602],{"id":5601},"anonymous-functions-closures-and-arrow-functions","Anonymous functions, closures, and arrow functions",[11,5604,5605,5606,5609,5610,5613,5614,5617,5618,5621,5622,5624],{},"An anonymous function (a closure) is a function value you can store and pass around. Unlike JavaScript, a classic closure does ",[1511,5607,5608],{},"not"," automatically capture the surrounding scope; you list the variables you want in a ",[15,5611,5612],{},"use"," clause, and they are captured ",[1511,5615,5616],{},"by value"," at creation time unless you write ",[15,5619,5620],{},"use (&$x)"," to capture by reference. Arrow functions (PHP 7.4), written with ",[15,5623,3466],{},", capture the enclosing scope automatically by value and are ideal for short callbacks.",[83,5626,5628],{"className":85,"code":5627,"language":87,"meta":88,"style":88},"$factor = 3;\n\n// Classic closure: name captured variables explicitly in `use`.\n$scaleByValue = function (int $n) use ($factor): int {\n    return $n * $factor;   // sees $factor as it was when the closure was created\n};\n\n// Capture by reference to see later changes to $factor:\n$scaleByRef = function (int $n) use (&$factor): int {\n    return $n * $factor;\n};\n\n// Arrow function: captures $factor automatically, by value.\n$scale = fn(int $n): int => $n * $factor;\n\n$factor = 10;\n$scaleByValue(2);  // 6   (captured 3 by value)\n$scaleByRef(2);    // 20  (sees the updated 10)\n",[15,5629,5630,5641,5645,5650,5678,5693,5697,5701,5706,5736,5747,5751,5755,5760,5788,5792,5802,5814],{"__ignoreMap":88},[92,5631,5632,5635,5637,5639],{"class":94,"line":95},[92,5633,5634],{"class":119},"$factor ",[92,5636,126],{"class":98},[92,5638,856],{"class":102},[92,5640,229],{"class":119},[92,5642,5643],{"class":94,"line":106},[92,5644,110],{"emptyLinePlaceholder":109},[92,5646,5647],{"class":94,"line":113},[92,5648,5649],{"class":134},"// Classic closure: name captured variables explicitly in `use`.\n",[92,5651,5652,5655,5657,5660,5662,5664,5667,5669,5672,5674,5676],{"class":94,"line":138},[92,5653,5654],{"class":119},"$scaleByValue ",[92,5656,126],{"class":98},[92,5658,5659],{"class":98}," function",[92,5661,3559],{"class":119},[92,5663,370],{"class":98},[92,5665,5666],{"class":119}," $n) ",[92,5668,5612],{"class":98},[92,5670,5671],{"class":119}," ($factor)",[92,5673,5185],{"class":98},[92,5675,5370],{"class":98},[92,5677,4695],{"class":119},[92,5679,5680,5682,5685,5687,5690],{"class":94,"line":143},[92,5681,5195],{"class":98},[92,5683,5684],{"class":119}," $n ",[92,5686,1959],{"class":98},[92,5688,5689],{"class":119}," $factor;   ",[92,5691,5692],{"class":134},"// sees $factor as it was when the closure was created\n",[92,5694,5695],{"class":94,"line":149},[92,5696,4802],{"class":119},[92,5698,5699],{"class":94,"line":155},[92,5700,110],{"emptyLinePlaceholder":109},[92,5702,5703],{"class":94,"line":161},[92,5704,5705],{"class":134},"// Capture by reference to see later changes to $factor:\n",[92,5707,5708,5711,5713,5715,5717,5719,5721,5723,5725,5727,5730,5732,5734],{"class":94,"line":166},[92,5709,5710],{"class":119},"$scaleByRef ",[92,5712,126],{"class":98},[92,5714,5659],{"class":98},[92,5716,3559],{"class":119},[92,5718,370],{"class":98},[92,5720,5666],{"class":119},[92,5722,5612],{"class":98},[92,5724,3559],{"class":119},[92,5726,1807],{"class":98},[92,5728,5729],{"class":119},"$factor)",[92,5731,5185],{"class":98},[92,5733,5370],{"class":98},[92,5735,4695],{"class":119},[92,5737,5738,5740,5742,5744],{"class":94,"line":187},[92,5739,5195],{"class":98},[92,5741,5684],{"class":119},[92,5743,1959],{"class":98},[92,5745,5746],{"class":119}," $factor;\n",[92,5748,5749],{"class":94,"line":217},[92,5750,4802],{"class":119},[92,5752,5753],{"class":94,"line":712},[92,5754,110],{"emptyLinePlaceholder":109},[92,5756,5757],{"class":94,"line":730},[92,5758,5759],{"class":134},"// Arrow function: captures $factor automatically, by value.\n",[92,5761,5762,5765,5767,5770,5772,5774,5777,5779,5781,5784,5786],{"class":94,"line":747},[92,5763,5764],{"class":119},"$scale ",[92,5766,126],{"class":98},[92,5768,5769],{"class":98}," fn",[92,5771,120],{"class":119},[92,5773,370],{"class":98},[92,5775,5776],{"class":119}," $n)",[92,5778,5185],{"class":98},[92,5780,5370],{"class":98},[92,5782,5783],{"class":119}," => $n ",[92,5785,1959],{"class":98},[92,5787,5746],{"class":119},[92,5789,5790],{"class":94,"line":763},[92,5791,110],{"emptyLinePlaceholder":109},[92,5793,5794,5796,5798,5800],{"class":94,"line":780},[92,5795,5634],{"class":119},[92,5797,126],{"class":98},[92,5799,1286],{"class":102},[92,5801,229],{"class":119},[92,5803,5804,5807,5809,5811],{"class":94,"line":785},[92,5805,5806],{"class":119},"$scaleByValue(",[92,5808,354],{"class":102},[92,5810,800],{"class":119},[92,5812,5813],{"class":134},"// 6   (captured 3 by value)\n",[92,5815,5816,5819,5821,5823],{"class":94,"line":2585},[92,5817,5818],{"class":119},"$scaleByRef(",[92,5820,354],{"class":102},[92,5822,2770],{"class":119},[92,5824,5825],{"class":134},"// 20  (sees the updated 10)\n",[242,5827,5829],{"id":5828},"callables-and-first-class-references","Callables and first-class references",[11,5831,5832,5833,5836,5837,5840,5841,5844,5845,5848],{},"Many standard functions take a \"callable,\" which PHP accepts in several forms: a function name as a string, an ",[15,5834,5835],{},"[$object, 'method']"," pair, an anonymous function, or an object with an ",[15,5838,5839],{},"__invoke"," method. PHP 8.1 added first-class callable syntax, ",[15,5842,5843],{},"strlen(...)",", which turns any function or method into a ",[15,5846,5847],{},"Closure"," you can pass around cleanly.",[83,5850,5852],{"className":85,"code":5851,"language":87,"meta":88,"style":88},"array_map('strtoupper', ['a', 'b']);   // ['A', 'B'] (function name as a string)\narray_map(strtoupper(...), ['a', 'b']); // same, using first-class callable syntax (8.1)\nusort($rows, [$sorter, 'compare']);    // [object, method] pair\n",[15,5853,5854,5877,5904],{"__ignoreMap":88},[92,5855,5856,5858,5860,5863,5865,5867,5869,5871,5874],{"class":94,"line":95},[92,5857,3322],{"class":102},[92,5859,120],{"class":119},[92,5861,5862],{"class":171},"'strtoupper'",[92,5864,2708],{"class":119},[92,5866,1844],{"class":171},[92,5868,195],{"class":119},[92,5870,198],{"class":171},[92,5872,5873],{"class":119},"]);   ",[92,5875,5876],{"class":134},"// ['A', 'B'] (function name as a string)\n",[92,5878,5879,5881,5883,5885,5887,5889,5892,5894,5896,5898,5901],{"class":94,"line":106},[92,5880,3322],{"class":102},[92,5882,120],{"class":119},[92,5884,2326],{"class":102},[92,5886,120],{"class":119},[92,5888,5335],{"class":98},[92,5890,5891],{"class":119},"), [",[92,5893,1844],{"class":171},[92,5895,195],{"class":119},[92,5897,198],{"class":171},[92,5899,5900],{"class":119},"]); ",[92,5902,5903],{"class":134},"// same, using first-class callable syntax (8.1)\n",[92,5905,5906,5908,5911,5914,5916],{"class":94,"line":113},[92,5907,4153],{"class":102},[92,5909,5910],{"class":119},"($rows, [$sorter, ",[92,5912,5913],{"class":171},"'compare'",[92,5915,495],{"class":119},[92,5917,5918],{"class":134},"// [object, method] pair\n",[242,5920,5922],{"id":5921},"generators","Generators",[11,5924,5925,5926,5929,5930,5932],{},"A generator is a function that uses ",[15,5927,5928],{},"yield"," to produce a sequence one value at a time instead of building and returning a whole array. Calling it does no work upfront; each ",[15,5931,5928],{}," pauses execution and hands back a value, resuming where it left off on the next iteration. This keeps memory flat when you process large or infinite sequences, which is why frameworks use generators for streaming database rows.",[83,5934,5936],{"className":85,"code":5935,"language":87,"meta":88,"style":88},"function countTo(int $limit): Generator {\n    for ($i = 1; $i \u003C= $limit; $i++) {\n        yield $i;              // pause here, resume on the next loop step\n    }\n}\nforeach (countTo(3) as $x) { echo $x; }   // prints 123, never holds an array\n\nfunction pairs(): Generator {\n    yield 'a' => 1;            // generators can yield key => value too\n    yield 'b' => 2;\n}\n",[15,5937,5938,5959,5982,5993,5997,6001,6029,6033,6049,6066,6078],{"__ignoreMap":88},[92,5939,5940,5942,5945,5947,5949,5952,5954,5957],{"class":94,"line":95},[92,5941,3556],{"class":98},[92,5943,5944],{"class":5161}," countTo",[92,5946,120],{"class":119},[92,5948,370],{"class":98},[92,5950,5951],{"class":119}," $limit)",[92,5953,5185],{"class":98},[92,5955,5956],{"class":102}," Generator",[92,5958,4695],{"class":119},[92,5960,5961,5964,5966,5968,5970,5972,5975,5978,5980],{"class":94,"line":106},[92,5962,5963],{"class":98},"    for",[92,5965,4909],{"class":119},[92,5967,126],{"class":98},[92,5969,1849],{"class":102},[92,5971,4916],{"class":119},[92,5973,5974],{"class":98},"\u003C=",[92,5976,5977],{"class":119}," $limit; $i",[92,5979,4926],{"class":98},[92,5981,4647],{"class":119},[92,5983,5984,5987,5990],{"class":94,"line":113},[92,5985,5986],{"class":98},"        yield",[92,5988,5989],{"class":119}," $i;              ",[92,5991,5992],{"class":134},"// pause here, resume on the next loop step\n",[92,5994,5995],{"class":94,"line":138},[92,5996,5104],{"class":119},[92,5998,5999],{"class":94,"line":143},[92,6000,4711],{"class":119},[92,6002,6003,6005,6007,6010,6012,6014,6016,6018,6021,6023,6026],{"class":94,"line":149},[92,6004,4394],{"class":98},[92,6006,3559],{"class":119},[92,6008,6009],{"class":5161},"countTo",[92,6011,120],{"class":119},[92,6013,1448],{"class":102},[92,6015,683],{"class":119},[92,6017,4497],{"class":98},[92,6019,6020],{"class":119}," $x) { ",[92,6022,60],{"class":102},[92,6024,6025],{"class":119}," $x; }   ",[92,6027,6028],{"class":134},"// prints 123, never holds an array\n",[92,6030,6031],{"class":94,"line":155},[92,6032,110],{"emptyLinePlaceholder":109},[92,6034,6035,6037,6040,6043,6045,6047],{"class":94,"line":161},[92,6036,3556],{"class":98},[92,6038,6039],{"class":5161}," pairs",[92,6041,6042],{"class":119},"()",[92,6044,5185],{"class":98},[92,6046,5956],{"class":102},[92,6048,4695],{"class":119},[92,6050,6051,6054,6056,6058,6060,6063],{"class":94,"line":166},[92,6052,6053],{"class":98},"    yield",[92,6055,192],{"class":171},[92,6057,1019],{"class":98},[92,6059,1849],{"class":102},[92,6061,6062],{"class":119},";            ",[92,6064,6065],{"class":134},"// generators can yield key => value too\n",[92,6067,6068,6070,6072,6074,6076],{"class":94,"line":187},[92,6069,6053],{"class":98},[92,6071,3009],{"class":171},[92,6073,1019],{"class":98},[92,6075,1225],{"class":102},[92,6077,229],{"class":119},[92,6079,6080],{"class":94,"line":217},[92,6081,4711],{"class":119},[11,6083,1792,6084,6086,6087,6089],{},[15,6085,5612],{},"-by-value rule is the closure detail that trips up JavaScript developers, who expect a closure to see later mutations of an outer variable; when you actually need that live link, capture by reference with ",[15,6088,5620],{}," and change it deliberately rather than by accident.",[39,6091,6093],{"id":6092},"object-oriented-programming","Object-Oriented Programming",[242,6095,6097,6098],{"id":6096},"classes-objects-and-this","Classes, objects, and ",[15,6099,6100],{},"$this",[11,6102,6103,6104,6106,6107,6109,6110,6112],{},"A class is a blueprint that bundles data (properties) and behavior (methods); an object is an instance created from it with ",[15,6105,3334],{},". Inside a method, ",[15,6108,6100],{}," refers to the current instance, and you access members with the ",[15,6111,1996],{}," operator. Properties should be typed and can have default values, and methods declare visibility just like properties.",[83,6114,6116],{"className":85,"code":6115,"language":87,"meta":88,"style":88},"class Rectangle {\n    public float $width;        // typed property\n    public float $height;\n\n    public function __construct(float $width, float $height) {\n        $this->width = $width;  // $this is the current instance\n        $this->height = $height;\n    }\n\n    public function area(): float {\n        return $this->width * $this->height;\n    }\n}\n\n$r = new Rectangle(3.0, 4.0);\n$r->area();      // 12.0  (-> accesses instance members)\n$r->width;       // 3.0\n",[15,6117,6118,6128,6142,6151,6155,6176,6194,6207,6211,6215,6232,6253,6257,6261,6265,6290,6306],{"__ignoreMap":88},[92,6119,6120,6123,6126],{"class":94,"line":95},[92,6121,6122],{"class":98},"class",[92,6124,6125],{"class":5161}," Rectangle",[92,6127,4695],{"class":119},[92,6129,6130,6133,6136,6139],{"class":94,"line":106},[92,6131,6132],{"class":98},"    public",[92,6134,6135],{"class":98}," float",[92,6137,6138],{"class":119}," $width;        ",[92,6140,6141],{"class":134},"// typed property\n",[92,6143,6144,6146,6148],{"class":94,"line":113},[92,6145,6132],{"class":98},[92,6147,6135],{"class":98},[92,6149,6150],{"class":119}," $height;\n",[92,6152,6153],{"class":94,"line":138},[92,6154,110],{"emptyLinePlaceholder":109},[92,6156,6157,6159,6161,6164,6166,6168,6171,6173],{"class":94,"line":143},[92,6158,6132],{"class":98},[92,6160,5659],{"class":98},[92,6162,6163],{"class":102}," __construct",[92,6165,120],{"class":119},[92,6167,373],{"class":98},[92,6169,6170],{"class":119}," $width, ",[92,6172,373],{"class":98},[92,6174,6175],{"class":119}," $height) {\n",[92,6177,6178,6181,6183,6186,6188,6191],{"class":94,"line":149},[92,6179,6180],{"class":102},"        $this",[92,6182,1996],{"class":98},[92,6184,6185],{"class":119},"width ",[92,6187,126],{"class":98},[92,6189,6190],{"class":119}," $width;  ",[92,6192,6193],{"class":134},"// $this is the current instance\n",[92,6195,6196,6198,6200,6203,6205],{"class":94,"line":155},[92,6197,6180],{"class":102},[92,6199,1996],{"class":98},[92,6201,6202],{"class":119},"height ",[92,6204,126],{"class":98},[92,6206,6150],{"class":119},[92,6208,6209],{"class":94,"line":161},[92,6210,5104],{"class":119},[92,6212,6213],{"class":94,"line":166},[92,6214,110],{"emptyLinePlaceholder":109},[92,6216,6217,6219,6221,6224,6226,6228,6230],{"class":94,"line":187},[92,6218,6132],{"class":98},[92,6220,5659],{"class":98},[92,6222,6223],{"class":5161}," area",[92,6225,6042],{"class":119},[92,6227,5185],{"class":98},[92,6229,6135],{"class":98},[92,6231,4695],{"class":119},[92,6233,6234,6237,6240,6242,6244,6246,6248,6250],{"class":94,"line":217},[92,6235,6236],{"class":98},"        return",[92,6238,6239],{"class":102}," $this",[92,6241,1996],{"class":98},[92,6243,6185],{"class":119},[92,6245,1959],{"class":98},[92,6247,6239],{"class":102},[92,6249,1996],{"class":98},[92,6251,6252],{"class":119},"height;\n",[92,6254,6255],{"class":94,"line":712},[92,6256,5104],{"class":119},[92,6258,6259],{"class":94,"line":730},[92,6260,4711],{"class":119},[92,6262,6263],{"class":94,"line":747},[92,6264,110],{"emptyLinePlaceholder":109},[92,6266,6267,6270,6272,6275,6277,6279,6282,6284,6287],{"class":94,"line":763},[92,6268,6269],{"class":119},"$r ",[92,6271,126],{"class":98},[92,6273,6274],{"class":98}," new",[92,6276,6125],{"class":102},[92,6278,120],{"class":119},[92,6280,6281],{"class":102},"3.0",[92,6283,195],{"class":119},[92,6285,6286],{"class":102},"4.0",[92,6288,6289],{"class":119},");\n",[92,6291,6292,6295,6297,6300,6303],{"class":94,"line":780},[92,6293,6294],{"class":119},"$r",[92,6296,1996],{"class":98},[92,6298,6299],{"class":5161},"area",[92,6301,6302],{"class":119},"();      ",[92,6304,6305],{"class":134},"// 12.0  (-> accesses instance members)\n",[92,6307,6308,6310,6312,6315],{"class":94,"line":785},[92,6309,6294],{"class":119},[92,6311,1996],{"class":98},[92,6313,6314],{"class":119},"width;       ",[92,6316,6317],{"class":134},"// 3.0\n",[242,6319,6321],{"id":6320},"visibility","Visibility",[11,6323,6324,6325,6328,6329,6332,6333,6336,6337,6339,6340,6342],{},"Each property and method has a visibility that controls where it can be accessed: ",[15,6326,6327],{},"public"," is reachable from anywhere, ",[15,6330,6331],{},"protected"," is reachable from the class and its subclasses, and ",[15,6334,6335],{},"private"," is reachable only from the declaring class. Defaulting to ",[15,6338,6335],{}," or ",[15,6341,6331],{}," and exposing behavior through public methods is the encapsulation idea PHP shares with Java and C#.",[83,6344,6346],{"className":85,"code":6345,"language":87,"meta":88,"style":88},"class BankAccount {\n    private float $balance = 0.0;      // hidden from outside code\n\n    public function deposit(float $amount): void {\n        $this->balance += $amount;     // internal code can touch it\n    }\n    public function getBalance(): float {\n        return $this->balance;         // exposed through a public method\n    }\n}\n",[15,6347,6348,6357,6377,6381,6403,6420,6424,6441,6455,6459],{"__ignoreMap":88},[92,6349,6350,6352,6355],{"class":94,"line":95},[92,6351,6122],{"class":98},[92,6353,6354],{"class":5161}," BankAccount",[92,6356,4695],{"class":119},[92,6358,6359,6362,6364,6367,6369,6372,6374],{"class":94,"line":106},[92,6360,6361],{"class":98},"    private",[92,6363,6135],{"class":98},[92,6365,6366],{"class":119}," $balance ",[92,6368,126],{"class":98},[92,6370,6371],{"class":102}," 0.0",[92,6373,946],{"class":119},[92,6375,6376],{"class":134},"// hidden from outside code\n",[92,6378,6379],{"class":94,"line":113},[92,6380,110],{"emptyLinePlaceholder":109},[92,6382,6383,6385,6387,6390,6392,6394,6397,6399,6401],{"class":94,"line":138},[92,6384,6132],{"class":98},[92,6386,5659],{"class":98},[92,6388,6389],{"class":5161}," deposit",[92,6391,120],{"class":119},[92,6393,373],{"class":98},[92,6395,6396],{"class":119}," $amount)",[92,6398,5185],{"class":98},[92,6400,5303],{"class":98},[92,6402,4695],{"class":119},[92,6404,6405,6407,6409,6412,6414,6417],{"class":94,"line":143},[92,6406,6180],{"class":102},[92,6408,1996],{"class":98},[92,6410,6411],{"class":119},"balance ",[92,6413,1182],{"class":98},[92,6415,6416],{"class":119}," $amount;     ",[92,6418,6419],{"class":134},"// internal code can touch it\n",[92,6421,6422],{"class":94,"line":149},[92,6423,5104],{"class":119},[92,6425,6426,6428,6430,6433,6435,6437,6439],{"class":94,"line":155},[92,6427,6132],{"class":98},[92,6429,5659],{"class":98},[92,6431,6432],{"class":5161}," getBalance",[92,6434,6042],{"class":119},[92,6436,5185],{"class":98},[92,6438,6135],{"class":98},[92,6440,4695],{"class":119},[92,6442,6443,6445,6447,6449,6452],{"class":94,"line":161},[92,6444,6236],{"class":98},[92,6446,6239],{"class":102},[92,6448,1996],{"class":98},[92,6450,6451],{"class":119},"balance;         ",[92,6453,6454],{"class":134},"// exposed through a public method\n",[92,6456,6457],{"class":94,"line":166},[92,6458,5104],{"class":119},[92,6460,6461],{"class":94,"line":187},[92,6462,4711],{"class":119},[242,6464,6466],{"id":6465},"constructors-and-constructor-promotion","Constructors and constructor promotion",[11,6468,6469,6472,6473,394,6475,6478,6479,6482],{},[15,6470,6471],{},"__construct"," is the constructor, called automatically by ",[15,6474,3334],{},[15,6476,6477],{},"__destruct"," runs when the object is destroyed. Because assigning constructor arguments to properties was so repetitive, PHP 8.0 added ",[1511,6480,6481],{},"constructor property promotion",": adding a visibility keyword to a constructor parameter declares the property and assigns it in one step, so you no longer write the property, the parameter, and the assignment separately. The two versions below are equivalent.",[83,6484,6486],{"className":85,"code":6485,"language":87,"meta":88,"style":88},"// Without promotion (the old, verbose way):\nclass PointOld {\n    public int $x;\n    public int $y;\n    public function __construct(int $x, int $y) {\n        $this->x = $x;\n        $this->y = $y;\n    }\n}\n\n// With constructor promotion (PHP 8.0): declare + assign in the signature.\nclass Point {\n    public function __construct(\n        public int $x = 0,\n        public int $y = 0,\n    ) {}\n}\n\n$p = new Point(2, 5);\n$p->x;   // 2\n",[15,6487,6488,6493,6502,6511,6520,6540,6553,6566,6570,6574,6578,6583,6592,6603,6619,6634,6639,6643,6647,6668],{"__ignoreMap":88},[92,6489,6490],{"class":94,"line":95},[92,6491,6492],{"class":134},"// Without promotion (the old, verbose way):\n",[92,6494,6495,6497,6500],{"class":94,"line":106},[92,6496,6122],{"class":98},[92,6498,6499],{"class":5161}," PointOld",[92,6501,4695],{"class":119},[92,6503,6504,6506,6508],{"class":94,"line":113},[92,6505,6132],{"class":98},[92,6507,5370],{"class":98},[92,6509,6510],{"class":119}," $x;\n",[92,6512,6513,6515,6517],{"class":94,"line":138},[92,6514,6132],{"class":98},[92,6516,5370],{"class":98},[92,6518,6519],{"class":119}," $y;\n",[92,6521,6522,6524,6526,6528,6530,6532,6535,6537],{"class":94,"line":143},[92,6523,6132],{"class":98},[92,6525,5659],{"class":98},[92,6527,6163],{"class":102},[92,6529,120],{"class":119},[92,6531,370],{"class":98},[92,6533,6534],{"class":119}," $x, ",[92,6536,370],{"class":98},[92,6538,6539],{"class":119}," $y) {\n",[92,6541,6542,6544,6546,6549,6551],{"class":94,"line":149},[92,6543,6180],{"class":102},[92,6545,1996],{"class":98},[92,6547,6548],{"class":119},"x ",[92,6550,126],{"class":98},[92,6552,6510],{"class":119},[92,6554,6555,6557,6559,6562,6564],{"class":94,"line":155},[92,6556,6180],{"class":102},[92,6558,1996],{"class":98},[92,6560,6561],{"class":119},"y ",[92,6563,126],{"class":98},[92,6565,6519],{"class":119},[92,6567,6568],{"class":94,"line":161},[92,6569,5104],{"class":119},[92,6571,6572],{"class":94,"line":166},[92,6573,4711],{"class":119},[92,6575,6576],{"class":94,"line":187},[92,6577,110],{"emptyLinePlaceholder":109},[92,6579,6580],{"class":94,"line":217},[92,6581,6582],{"class":134},"// With constructor promotion (PHP 8.0): declare + assign in the signature.\n",[92,6584,6585,6587,6590],{"class":94,"line":712},[92,6586,6122],{"class":98},[92,6588,6589],{"class":5161}," Point",[92,6591,4695],{"class":119},[92,6593,6594,6596,6598,6600],{"class":94,"line":730},[92,6595,6132],{"class":98},[92,6597,5659],{"class":98},[92,6599,6163],{"class":102},[92,6601,6602],{"class":119},"(\n",[92,6604,6605,6608,6610,6613,6615,6617],{"class":94,"line":747},[92,6606,6607],{"class":98},"        public",[92,6609,5370],{"class":98},[92,6611,6612],{"class":119}," $x ",[92,6614,126],{"class":98},[92,6616,331],{"class":102},[92,6618,4772],{"class":119},[92,6620,6621,6623,6625,6628,6630,6632],{"class":94,"line":763},[92,6622,6607],{"class":98},[92,6624,5370],{"class":98},[92,6626,6627],{"class":119}," $y ",[92,6629,126],{"class":98},[92,6631,331],{"class":102},[92,6633,4772],{"class":119},[92,6635,6636],{"class":94,"line":780},[92,6637,6638],{"class":119},"    ) {}\n",[92,6640,6641],{"class":94,"line":785},[92,6642,4711],{"class":119},[92,6644,6645],{"class":94,"line":2585},[92,6646,110],{"emptyLinePlaceholder":109},[92,6648,6649,6652,6654,6656,6658,6660,6662,6664,6666],{"class":94,"line":2605},[92,6650,6651],{"class":119},"$p ",[92,6653,126],{"class":98},[92,6655,6274],{"class":98},[92,6657,6589],{"class":102},[92,6659,120],{"class":119},[92,6661,354],{"class":102},[92,6663,195],{"class":119},[92,6665,1463],{"class":102},[92,6667,6289],{"class":119},[92,6669,6670,6673,6675,6678],{"class":94,"line":2634},[92,6671,6672],{"class":119},"$p",[92,6674,1996],{"class":98},[92,6676,6677],{"class":119},"x;   ",[92,6679,2582],{"class":134},[242,6681,6683],{"id":6682},"readonly-properties","readonly properties",[11,6685,6686,6687,6690],{},"A ",[15,6688,6689],{},"readonly"," property (PHP 8.1) can be assigned exactly once, normally inside the constructor, and any later write throws an error. This gives you immutable value objects without writing a private property plus a getter, and it pairs naturally with constructor promotion.",[83,6692,6694],{"className":85,"code":6693,"language":87,"meta":88,"style":88},"class Money {\n    public function __construct(\n        public readonly int $amount,\n        public readonly string $currency = 'USD',\n    ) {}\n}\n\n$m = new Money(1500);\n$m->amount;          // 1500\n$m->amount = 2000;   // Error: cannot modify a readonly property\n",[15,6695,6696,6705,6715,6727,6745,6749,6753,6757,6775,6788],{"__ignoreMap":88},[92,6697,6698,6700,6703],{"class":94,"line":95},[92,6699,6122],{"class":98},[92,6701,6702],{"class":5161}," Money",[92,6704,4695],{"class":119},[92,6706,6707,6709,6711,6713],{"class":94,"line":106},[92,6708,6132],{"class":98},[92,6710,5659],{"class":98},[92,6712,6163],{"class":102},[92,6714,6602],{"class":119},[92,6716,6717,6719,6722,6724],{"class":94,"line":113},[92,6718,6607],{"class":98},[92,6720,6721],{"class":98}," readonly",[92,6723,5370],{"class":98},[92,6725,6726],{"class":119}," $amount,\n",[92,6728,6729,6731,6733,6735,6738,6740,6743],{"class":94,"line":138},[92,6730,6607],{"class":98},[92,6732,6721],{"class":98},[92,6734,5188],{"class":98},[92,6736,6737],{"class":119}," $currency ",[92,6739,126],{"class":98},[92,6741,6742],{"class":171}," 'USD'",[92,6744,4772],{"class":119},[92,6746,6747],{"class":94,"line":143},[92,6748,6638],{"class":119},[92,6750,6751],{"class":94,"line":149},[92,6752,4711],{"class":119},[92,6754,6755],{"class":94,"line":155},[92,6756,110],{"emptyLinePlaceholder":109},[92,6758,6759,6762,6764,6766,6768,6770,6773],{"class":94,"line":161},[92,6760,6761],{"class":119},"$m ",[92,6763,126],{"class":98},[92,6765,6274],{"class":98},[92,6767,6702],{"class":102},[92,6769,120],{"class":119},[92,6771,6772],{"class":102},"1500",[92,6774,6289],{"class":119},[92,6776,6777,6780,6782,6785],{"class":94,"line":166},[92,6778,6779],{"class":119},"$m",[92,6781,1996],{"class":98},[92,6783,6784],{"class":119},"amount;          ",[92,6786,6787],{"class":134},"// 1500\n",[92,6789,6790,6792,6794,6797,6799,6802,6804],{"class":94,"line":187},[92,6791,6779],{"class":119},[92,6793,1996],{"class":98},[92,6795,6796],{"class":119},"amount ",[92,6798,126],{"class":98},[92,6800,6801],{"class":102}," 2000",[92,6803,309],{"class":119},[92,6805,6806],{"class":134},"// Error: cannot modify a readonly property\n",[242,6808,6810],{"id":6809},"static-members-and-class-constants","Static members and class constants",[11,6812,6686,6813,6815,6816,6819,6820,6822,6823,6826,6827,6830],{},[15,6814,5146],{}," property or method belongs to the class itself rather than to any instance, so you call it with ",[15,6817,6818],{},"::"," and it shares one value across all objects. A class constant, declared with ",[15,6821,816],{},", is a fixed value namespaced under the class. Inside the class, ",[15,6824,6825],{},"self::"," refers to the class where the code is written and ",[15,6828,6829],{},"static::"," refers to the class that was actually called (this difference is \"late static binding,\" which matters with inheritance).",[83,6832,6834],{"className":85,"code":6833,"language":87,"meta":88,"style":88},"class Counter {\n    public const START = 0;            // class constant, accessed with ::\n    private static int $count = 0;     // shared across all instances\n\n    public static function next(): int {\n        return ++self::$count;         // :: reaches static members\n    }\n}\n\nCounter::next();        // 1\nCounter::next();        // 2\necho Counter::START;    // 0\necho Counter::class;    // 'Counter'  (the ::class constant gives the full name)\n",[15,6835,6836,6845,6864,6885,6889,6908,6921,6925,6929,6933,6949,6961,6977],{"__ignoreMap":88},[92,6837,6838,6840,6843],{"class":94,"line":95},[92,6839,6122],{"class":98},[92,6841,6842],{"class":5161}," Counter",[92,6844,4695],{"class":119},[92,6846,6847,6849,6852,6855,6857,6859,6861],{"class":94,"line":106},[92,6848,6132],{"class":98},[92,6850,6851],{"class":98}," const",[92,6853,6854],{"class":102}," START",[92,6856,853],{"class":98},[92,6858,331],{"class":102},[92,6860,6062],{"class":119},[92,6862,6863],{"class":134},"// class constant, accessed with ::\n",[92,6865,6866,6868,6871,6873,6876,6878,6880,6882],{"class":94,"line":113},[92,6867,6361],{"class":98},[92,6869,6870],{"class":98}," static",[92,6872,5370],{"class":98},[92,6874,6875],{"class":119}," $count ",[92,6877,126],{"class":98},[92,6879,331],{"class":102},[92,6881,724],{"class":119},[92,6883,6884],{"class":134},"// shared across all instances\n",[92,6886,6887],{"class":94,"line":138},[92,6888,110],{"emptyLinePlaceholder":109},[92,6890,6891,6893,6895,6897,6900,6902,6904,6906],{"class":94,"line":143},[92,6892,6132],{"class":98},[92,6894,6870],{"class":98},[92,6896,5659],{"class":98},[92,6898,6899],{"class":5161}," next",[92,6901,6042],{"class":119},[92,6903,5185],{"class":98},[92,6905,5370],{"class":98},[92,6907,4695],{"class":119},[92,6909,6910,6912,6915,6918],{"class":94,"line":149},[92,6911,6236],{"class":98},[92,6913,6914],{"class":98}," ++self::",[92,6916,6917],{"class":119},"$count;         ",[92,6919,6920],{"class":134},"// :: reaches static members\n",[92,6922,6923],{"class":94,"line":155},[92,6924,5104],{"class":119},[92,6926,6927],{"class":94,"line":161},[92,6928,4711],{"class":119},[92,6930,6931],{"class":94,"line":166},[92,6932,110],{"emptyLinePlaceholder":109},[92,6934,6935,6938,6940,6943,6946],{"class":94,"line":187},[92,6936,6937],{"class":102},"Counter",[92,6939,6818],{"class":98},[92,6941,6942],{"class":5161},"next",[92,6944,6945],{"class":119},"();        ",[92,6947,6948],{"class":134},"// 1\n",[92,6950,6951,6953,6955,6957,6959],{"class":94,"line":217},[92,6952,6937],{"class":102},[92,6954,6818],{"class":98},[92,6956,6942],{"class":5161},[92,6958,6945],{"class":119},[92,6960,2582],{"class":134},[92,6962,6963,6965,6967,6969,6972,6974],{"class":94,"line":712},[92,6964,60],{"class":102},[92,6966,6842],{"class":102},[92,6968,6818],{"class":98},[92,6970,6971],{"class":102},"START",[92,6973,211],{"class":119},[92,6975,6976],{"class":134},"// 0\n",[92,6978,6979,6981,6983,6986,6988],{"class":94,"line":730},[92,6980,60],{"class":102},[92,6982,6842],{"class":102},[92,6984,6985],{"class":98},"::class",[92,6987,211],{"class":119},[92,6989,6990],{"class":134},"// 'Counter'  (the ::class constant gives the full name)\n",[242,6992,6994],{"id":6993},"inheritance","Inheritance",[11,6996,6997,6998,7001,7002,7005,7006,7009],{},"A class ",[15,6999,7000],{},"extends"," one parent, inheriting its properties and methods, and can override any method by redeclaring it; call the parent's version with ",[15,7003,7004],{},"parent::",". Mark a class or method ",[15,7007,7008],{},"final"," to forbid extension or overriding. PHP allows only single inheritance, which is why interfaces and traits (below) exist to share behavior more flexibly.",[83,7011,7013],{"className":85,"code":7012,"language":87,"meta":88,"style":88},"class Animal {\n    public function __construct(protected string $name) {}\n    public function speak(): string {\n        return \"$this->name makes a sound\";\n    }\n}\n\nclass Dog extends Animal {\n    public function speak(): string {          // override\n        return parent::speak() . ' (a bark)';  // call the parent version too\n    }\n}\n\n(new Dog('Rex'))->speak();   // 'Rex makes a sound (a bark)'\n",[15,7014,7015,7024,7041,7058,7075,7079,7083,7087,7101,7121,7144,7148,7152,7156],{"__ignoreMap":88},[92,7016,7017,7019,7022],{"class":94,"line":95},[92,7018,6122],{"class":98},[92,7020,7021],{"class":5161}," Animal",[92,7023,4695],{"class":119},[92,7025,7026,7028,7030,7032,7034,7036,7038],{"class":94,"line":106},[92,7027,6132],{"class":98},[92,7029,5659],{"class":98},[92,7031,6163],{"class":102},[92,7033,120],{"class":119},[92,7035,6331],{"class":98},[92,7037,5188],{"class":98},[92,7039,7040],{"class":119}," $name) {}\n",[92,7042,7043,7045,7047,7050,7052,7054,7056],{"class":94,"line":113},[92,7044,6132],{"class":98},[92,7046,5659],{"class":98},[92,7048,7049],{"class":5161}," speak",[92,7051,6042],{"class":119},[92,7053,5185],{"class":98},[92,7055,5188],{"class":98},[92,7057,4695],{"class":119},[92,7059,7060,7062,7064,7066,7068,7070,7073],{"class":94,"line":138},[92,7061,6236],{"class":98},[92,7063,5198],{"class":171},[92,7065,6100],{"class":119},[92,7067,1996],{"class":98},[92,7069,5271],{"class":119},[92,7071,7072],{"class":171}," makes a sound\"",[92,7074,229],{"class":119},[92,7076,7077],{"class":94,"line":143},[92,7078,5104],{"class":119},[92,7080,7081],{"class":94,"line":149},[92,7082,4711],{"class":119},[92,7084,7085],{"class":94,"line":155},[92,7086,110],{"emptyLinePlaceholder":109},[92,7088,7089,7091,7094,7097,7099],{"class":94,"line":161},[92,7090,6122],{"class":98},[92,7092,7093],{"class":5161}," Dog",[92,7095,7096],{"class":98}," extends",[92,7098,7021],{"class":5161},[92,7100,4695],{"class":119},[92,7102,7103,7105,7107,7109,7111,7113,7115,7118],{"class":94,"line":166},[92,7104,6132],{"class":98},[92,7106,5659],{"class":98},[92,7108,7049],{"class":5161},[92,7110,6042],{"class":119},[92,7112,5185],{"class":98},[92,7114,5188],{"class":98},[92,7116,7117],{"class":119}," {          ",[92,7119,7120],{"class":134},"// override\n",[92,7122,7123,7125,7128,7131,7134,7136,7139,7141],{"class":94,"line":187},[92,7124,6236],{"class":98},[92,7126,7127],{"class":98}," parent::",[92,7129,7130],{"class":5161},"speak",[92,7132,7133],{"class":119},"() ",[92,7135,81],{"class":98},[92,7137,7138],{"class":171}," ' (a bark)'",[92,7140,2279],{"class":119},[92,7142,7143],{"class":134},"// call the parent version too\n",[92,7145,7146],{"class":94,"line":217},[92,7147,5104],{"class":119},[92,7149,7150],{"class":94,"line":712},[92,7151,4711],{"class":119},[92,7153,7154],{"class":94,"line":730},[92,7155,110],{"emptyLinePlaceholder":109},[92,7157,7158,7160,7162,7164,7166,7169,7172,7174,7176,7179],{"class":94,"line":747},[92,7159,120],{"class":119},[92,7161,3334],{"class":98},[92,7163,7093],{"class":102},[92,7165,120],{"class":119},[92,7167,7168],{"class":171},"'Rex'",[92,7170,7171],{"class":119},"))",[92,7173,1996],{"class":98},[92,7175,7130],{"class":5161},[92,7177,7178],{"class":119},"();   ",[92,7180,7181],{"class":134},"// 'Rex makes a sound (a bark)'\n",[242,7183,7185],{"id":7184},"abstract-classes","Abstract classes",[11,7187,7188,7189,7192],{},"An abstract class is a class you cannot instantiate on its own; it exists to be extended, and it can mix fully-written methods with ",[1511,7190,7191],{},"abstract"," methods that have a signature but no body. Every concrete subclass must implement each abstract method, so an abstract class is the tool for \"these types share this common code, but each must fill in this one piece.\" You reach for it (rather than an interface) when subclasses genuinely share implementation and state.",[83,7194,7196],{"className":85,"code":7195,"language":87,"meta":88,"style":88},"abstract class Shape {\n    abstract public function area(): float;    // no body; subclasses must implement it\n\n    public function describe(): string {       // shared, concrete method\n        return 'Area is ' . round($this->area(), 2);\n    }\n}\n\nclass Circle extends Shape {\n    public function __construct(private float $r) {}\n    public function area(): float {\n        return M_PI * $this->r ** 2;           // ** binds tighter than *\n    }\n}\n\n// new Shape();  would be a fatal error: cannot instantiate an abstract class\n(new Circle(2))->describe();   // 'Area is 12.57'\n",[15,7197,7198,7210,7233,7237,7258,7285,7289,7293,7297,7310,7327,7343,7369,7373,7377,7381,7386],{"__ignoreMap":88},[92,7199,7200,7202,7205,7208],{"class":94,"line":95},[92,7201,7191],{"class":98},[92,7203,7204],{"class":98}," class",[92,7206,7207],{"class":5161}," Shape",[92,7209,4695],{"class":119},[92,7211,7212,7215,7218,7220,7222,7224,7226,7228,7230],{"class":94,"line":106},[92,7213,7214],{"class":98},"    abstract",[92,7216,7217],{"class":98}," public",[92,7219,5659],{"class":98},[92,7221,6223],{"class":5161},[92,7223,6042],{"class":119},[92,7225,5185],{"class":98},[92,7227,6135],{"class":98},[92,7229,211],{"class":119},[92,7231,7232],{"class":134},"// no body; subclasses must implement it\n",[92,7234,7235],{"class":94,"line":113},[92,7236,110],{"emptyLinePlaceholder":109},[92,7238,7239,7241,7243,7246,7248,7250,7252,7255],{"class":94,"line":138},[92,7240,6132],{"class":98},[92,7242,5659],{"class":98},[92,7244,7245],{"class":5161}," describe",[92,7247,6042],{"class":119},[92,7249,5185],{"class":98},[92,7251,5188],{"class":98},[92,7253,7254],{"class":119}," {       ",[92,7256,7257],{"class":134},"// shared, concrete method\n",[92,7259,7260,7262,7265,7267,7270,7272,7274,7276,7278,7281,7283],{"class":94,"line":143},[92,7261,6236],{"class":98},[92,7263,7264],{"class":171}," 'Area is '",[92,7266,2108],{"class":98},[92,7268,7269],{"class":102}," round",[92,7271,120],{"class":119},[92,7273,6100],{"class":102},[92,7275,1996],{"class":98},[92,7277,6299],{"class":5161},[92,7279,7280],{"class":119},"(), ",[92,7282,354],{"class":102},[92,7284,6289],{"class":119},[92,7286,7287],{"class":94,"line":149},[92,7288,5104],{"class":119},[92,7290,7291],{"class":94,"line":155},[92,7292,4711],{"class":119},[92,7294,7295],{"class":94,"line":161},[92,7296,110],{"emptyLinePlaceholder":109},[92,7298,7299,7301,7304,7306,7308],{"class":94,"line":166},[92,7300,6122],{"class":98},[92,7302,7303],{"class":5161}," Circle",[92,7305,7096],{"class":98},[92,7307,7207],{"class":5161},[92,7309,4695],{"class":119},[92,7311,7312,7314,7316,7318,7320,7322,7324],{"class":94,"line":187},[92,7313,6132],{"class":98},[92,7315,5659],{"class":98},[92,7317,6163],{"class":102},[92,7319,120],{"class":119},[92,7321,6335],{"class":98},[92,7323,6135],{"class":98},[92,7325,7326],{"class":119}," $r) {}\n",[92,7328,7329,7331,7333,7335,7337,7339,7341],{"class":94,"line":217},[92,7330,6132],{"class":98},[92,7332,5659],{"class":98},[92,7334,6223],{"class":5161},[92,7336,6042],{"class":119},[92,7338,5185],{"class":98},[92,7340,6135],{"class":98},[92,7342,4695],{"class":119},[92,7344,7345,7347,7350,7353,7355,7357,7360,7362,7364,7366],{"class":94,"line":712},[92,7346,6236],{"class":98},[92,7348,7349],{"class":102}," M_PI",[92,7351,7352],{"class":98}," *",[92,7354,6239],{"class":102},[92,7356,1996],{"class":98},[92,7358,7359],{"class":119},"r ",[92,7361,1165],{"class":98},[92,7363,1225],{"class":102},[92,7365,1572],{"class":119},[92,7367,7368],{"class":134},"// ** binds tighter than *\n",[92,7370,7371],{"class":94,"line":730},[92,7372,5104],{"class":119},[92,7374,7375],{"class":94,"line":747},[92,7376,4711],{"class":119},[92,7378,7379],{"class":94,"line":763},[92,7380,110],{"emptyLinePlaceholder":109},[92,7382,7383],{"class":94,"line":780},[92,7384,7385],{"class":134},"// new Shape();  would be a fatal error: cannot instantiate an abstract class\n",[92,7387,7388,7390,7392,7394,7396,7398,7400,7402,7405,7407],{"class":94,"line":785},[92,7389,120],{"class":119},[92,7391,3334],{"class":98},[92,7393,7303],{"class":102},[92,7395,120],{"class":119},[92,7397,354],{"class":102},[92,7399,7171],{"class":119},[92,7401,1996],{"class":98},[92,7403,7404],{"class":5161},"describe",[92,7406,7178],{"class":119},[92,7408,7409],{"class":134},"// 'Area is 12.57'\n",[242,7411,7413],{"id":7412},"interfaces","Interfaces",[11,7415,7416,7417,7420,7421,7424],{},"An interface is a pure contract: a list of public method signatures (and optionally constants) with no implementation and no state. A class promises to provide every listed method by declaring ",[15,7418,7419],{},"implements",", and because a class can implement ",[1511,7422,7423],{},"many"," interfaces while extending only one class, interfaces are how PHP gets the flexibility of multiple inheritance for behavior without its problems. Use an interface when unrelated classes must be interchangeable through a shared set of methods.",[83,7426,7428],{"className":85,"code":7427,"language":87,"meta":88,"style":88},"interface Comparable {\n    public function compareTo(self $other): int;   // signature only\n}\n\ninterface JsonSerializable {\n    public function jsonSerialize(): mixed;\n}\n\n// A class can implement several interfaces at once:\nclass Version implements Comparable, JsonSerializable {\n    public function __construct(private int $number) {}\n\n    public function compareTo(self $other): int {\n        return $this->number \u003C=> $other->number;\n    }\n    public function jsonSerialize(): mixed {\n        return ['version' => $this->number];\n    }\n}\n",[15,7429,7430,7440,7465,7469,7473,7482,7500,7504,7508,7513,7532,7549,7553,7573,7594,7598,7614,7632,7636],{"__ignoreMap":88},[92,7431,7432,7435,7438],{"class":94,"line":95},[92,7433,7434],{"class":98},"interface",[92,7436,7437],{"class":5161}," Comparable",[92,7439,4695],{"class":119},[92,7441,7442,7444,7446,7449,7451,7453,7456,7458,7460,7462],{"class":94,"line":106},[92,7443,6132],{"class":98},[92,7445,5659],{"class":98},[92,7447,7448],{"class":5161}," compareTo",[92,7450,120],{"class":119},[92,7452,5143],{"class":98},[92,7454,7455],{"class":119}," $other)",[92,7457,5185],{"class":98},[92,7459,5370],{"class":98},[92,7461,309],{"class":119},[92,7463,7464],{"class":134},"// signature only\n",[92,7466,7467],{"class":94,"line":113},[92,7468,4711],{"class":119},[92,7470,7471],{"class":94,"line":138},[92,7472,110],{"emptyLinePlaceholder":109},[92,7474,7475,7477,7480],{"class":94,"line":143},[92,7476,7434],{"class":98},[92,7478,7479],{"class":5161}," JsonSerializable",[92,7481,4695],{"class":119},[92,7483,7484,7486,7488,7491,7493,7495,7498],{"class":94,"line":149},[92,7485,6132],{"class":98},[92,7487,5659],{"class":98},[92,7489,7490],{"class":5161}," jsonSerialize",[92,7492,6042],{"class":119},[92,7494,5185],{"class":98},[92,7496,7497],{"class":98}," mixed",[92,7499,229],{"class":119},[92,7501,7502],{"class":94,"line":155},[92,7503,4711],{"class":119},[92,7505,7506],{"class":94,"line":161},[92,7507,110],{"emptyLinePlaceholder":109},[92,7509,7510],{"class":94,"line":166},[92,7511,7512],{"class":134},"// A class can implement several interfaces at once:\n",[92,7514,7515,7517,7520,7523,7525,7527,7530],{"class":94,"line":187},[92,7516,6122],{"class":98},[92,7518,7519],{"class":5161}," Version",[92,7521,7522],{"class":98}," implements",[92,7524,7437],{"class":5161},[92,7526,195],{"class":119},[92,7528,7529],{"class":102},"JsonSerializable",[92,7531,4695],{"class":119},[92,7533,7534,7536,7538,7540,7542,7544,7546],{"class":94,"line":217},[92,7535,6132],{"class":98},[92,7537,5659],{"class":98},[92,7539,6163],{"class":102},[92,7541,120],{"class":119},[92,7543,6335],{"class":98},[92,7545,5370],{"class":98},[92,7547,7548],{"class":119}," $number) {}\n",[92,7550,7551],{"class":94,"line":712},[92,7552,110],{"emptyLinePlaceholder":109},[92,7554,7555,7557,7559,7561,7563,7565,7567,7569,7571],{"class":94,"line":730},[92,7556,6132],{"class":98},[92,7558,5659],{"class":98},[92,7560,7448],{"class":5161},[92,7562,120],{"class":119},[92,7564,5143],{"class":98},[92,7566,7455],{"class":119},[92,7568,5185],{"class":98},[92,7570,5370],{"class":98},[92,7572,4695],{"class":119},[92,7574,7575,7577,7579,7581,7584,7586,7589,7591],{"class":94,"line":747},[92,7576,6236],{"class":98},[92,7578,6239],{"class":102},[92,7580,1996],{"class":98},[92,7582,7583],{"class":119},"number ",[92,7585,1368],{"class":98},[92,7587,7588],{"class":119}," $other",[92,7590,1996],{"class":98},[92,7592,7593],{"class":119},"number;\n",[92,7595,7596],{"class":94,"line":763},[92,7597,5104],{"class":119},[92,7599,7600,7602,7604,7606,7608,7610,7612],{"class":94,"line":780},[92,7601,6132],{"class":98},[92,7603,5659],{"class":98},[92,7605,7490],{"class":5161},[92,7607,6042],{"class":119},[92,7609,5185],{"class":98},[92,7611,7497],{"class":98},[92,7613,4695],{"class":119},[92,7615,7616,7618,7620,7623,7625,7627,7629],{"class":94,"line":785},[92,7617,6236],{"class":98},[92,7619,347],{"class":119},[92,7621,7622],{"class":171},"'version'",[92,7624,1019],{"class":98},[92,7626,6239],{"class":102},[92,7628,1996],{"class":98},[92,7630,7631],{"class":119},"number];\n",[92,7633,7634],{"class":94,"line":2585},[92,7635,5104],{"class":119},[92,7637,7638],{"class":94,"line":2605},[92,7639,4711],{"class":119},[11,7641,7642,7643,7646,7647,7650],{},"The rule of thumb: an interface says ",[1511,7644,7645],{},"what"," a class can do, an abstract class provides ",[1511,7648,7649],{},"how"," for the parts that are shared. If you find yourself putting real method bodies or properties in an \"interface,\" you actually want an abstract class.",[242,7652,7654],{"id":7653},"traits","Traits",[11,7656,7657,7658,7660,7661,834,7664,81],{},"A trait is a bundle of methods (and properties) that you inject into a class with ",[15,7659,5612],{},", letting you share implementation across classes that do not share an ancestor. It exists specifically to work around single inheritance: instead of forcing every class that needs timestamp behavior into one base class, you drop the behavior in with a trait. When two traits collide on a method name, you resolve it explicitly with ",[15,7662,7663],{},"insteadof",[15,7665,4497],{},[83,7667,7669],{"className":85,"code":7668,"language":87,"meta":88,"style":88},"trait Timestamps {\n    public ?int $updatedAt = null;\n    public function touch(): void {\n        $this->updatedAt = time();\n    }\n}\n\ntrait Identifiable {\n    public string $id;\n    public function assignId(): void {\n        $this->id = uniqid();\n    }\n}\n\nclass Article {\n    use Timestamps, Identifiable;   // mix in both sets of methods\n    public function __construct(public string $title) {}\n}\n\n$a = new Article('Hello');\n$a->assignId();\n$a->touch();   // both trait methods are now part of Article\n",[15,7670,7671,7681,7697,7714,7731,7735,7739,7743,7752,7761,7778,7794,7798,7802,7806,7815,7832,7849,7853,7857,7874,7886],{"__ignoreMap":88},[92,7672,7673,7676,7679],{"class":94,"line":95},[92,7674,7675],{"class":98},"trait",[92,7677,7678],{"class":5161}," Timestamps",[92,7680,4695],{"class":119},[92,7682,7683,7685,7688,7691,7693,7695],{"class":94,"line":106},[92,7684,6132],{"class":98},[92,7686,7687],{"class":98}," ?int",[92,7689,7690],{"class":119}," $updatedAt ",[92,7692,126],{"class":98},[92,7694,1031],{"class":102},[92,7696,229],{"class":119},[92,7698,7699,7701,7703,7706,7708,7710,7712],{"class":94,"line":113},[92,7700,6132],{"class":98},[92,7702,5659],{"class":98},[92,7704,7705],{"class":5161}," touch",[92,7707,6042],{"class":119},[92,7709,5185],{"class":98},[92,7711,5303],{"class":98},[92,7713,4695],{"class":119},[92,7715,7716,7718,7720,7723,7725,7728],{"class":94,"line":138},[92,7717,6180],{"class":102},[92,7719,1996],{"class":98},[92,7721,7722],{"class":119},"updatedAt ",[92,7724,126],{"class":98},[92,7726,7727],{"class":102}," time",[92,7729,7730],{"class":119},"();\n",[92,7732,7733],{"class":94,"line":143},[92,7734,5104],{"class":119},[92,7736,7737],{"class":94,"line":149},[92,7738,4711],{"class":119},[92,7740,7741],{"class":94,"line":155},[92,7742,110],{"emptyLinePlaceholder":109},[92,7744,7745,7747,7750],{"class":94,"line":161},[92,7746,7675],{"class":98},[92,7748,7749],{"class":5161}," Identifiable",[92,7751,4695],{"class":119},[92,7753,7754,7756,7758],{"class":94,"line":166},[92,7755,6132],{"class":98},[92,7757,5188],{"class":98},[92,7759,7760],{"class":119}," $id;\n",[92,7762,7763,7765,7767,7770,7772,7774,7776],{"class":94,"line":187},[92,7764,6132],{"class":98},[92,7766,5659],{"class":98},[92,7768,7769],{"class":5161}," assignId",[92,7771,6042],{"class":119},[92,7773,5185],{"class":98},[92,7775,5303],{"class":98},[92,7777,4695],{"class":119},[92,7779,7780,7782,7784,7787,7789,7792],{"class":94,"line":217},[92,7781,6180],{"class":102},[92,7783,1996],{"class":98},[92,7785,7786],{"class":119},"id ",[92,7788,126],{"class":98},[92,7790,7791],{"class":102}," uniqid",[92,7793,7730],{"class":119},[92,7795,7796],{"class":94,"line":712},[92,7797,5104],{"class":119},[92,7799,7800],{"class":94,"line":730},[92,7801,4711],{"class":119},[92,7803,7804],{"class":94,"line":747},[92,7805,110],{"emptyLinePlaceholder":109},[92,7807,7808,7810,7813],{"class":94,"line":763},[92,7809,6122],{"class":98},[92,7811,7812],{"class":5161}," Article",[92,7814,4695],{"class":119},[92,7816,7817,7820,7822,7824,7827,7829],{"class":94,"line":780},[92,7818,7819],{"class":98},"    use",[92,7821,7678],{"class":102},[92,7823,195],{"class":119},[92,7825,7826],{"class":102},"Identifiable",[92,7828,309],{"class":119},[92,7830,7831],{"class":134},"// mix in both sets of methods\n",[92,7833,7834,7836,7838,7840,7842,7844,7846],{"class":94,"line":785},[92,7835,6132],{"class":98},[92,7837,5659],{"class":98},[92,7839,6163],{"class":102},[92,7841,120],{"class":119},[92,7843,6327],{"class":98},[92,7845,5188],{"class":98},[92,7847,7848],{"class":119}," $title) {}\n",[92,7850,7851],{"class":94,"line":2585},[92,7852,4711],{"class":119},[92,7854,7855],{"class":94,"line":2605},[92,7856,110],{"emptyLinePlaceholder":109},[92,7858,7859,7861,7863,7865,7867,7869,7872],{"class":94,"line":2634},[92,7860,321],{"class":119},[92,7862,126],{"class":98},[92,7864,6274],{"class":98},[92,7866,7812],{"class":102},[92,7868,120],{"class":119},[92,7870,7871],{"class":171},"'Hello'",[92,7873,6289],{"class":119},[92,7875,7876,7879,7881,7884],{"class":94,"line":2651},[92,7877,7878],{"class":119},"$a",[92,7880,1996],{"class":98},[92,7882,7883],{"class":5161},"assignId",[92,7885,7730],{"class":119},[92,7887,7888,7890,7892,7895,7897],{"class":94,"line":2671},[92,7889,7878],{"class":119},[92,7891,1996],{"class":98},[92,7893,7894],{"class":5161},"touch",[92,7896,7178],{"class":119},[92,7898,7899],{"class":134},"// both trait methods are now part of Article\n",[242,7901,7903],{"id":7902},"enums","Enums",[11,7905,7906,7907,7910,7911,7914,7915,6339,7917,7919,7920,7923,7924,7927,7928,7930],{},"An enum (PHP 8.1) defines a type with a fixed set of named values, replacing the old habit of using loose class constants. A ",[1511,7908,7909],{},"pure"," enum just names its cases, while a ",[1511,7912,7913],{},"backed"," enum gives each case a scalar value (",[15,7916,376],{},[15,7918,370],{},"), which is what you store in a database or send over an API. Enums can hold methods and constants and implement interfaces, and backed enums add ",[15,7921,7922],{},"from()"," (throws on an unknown value) and ",[15,7925,7926],{},"tryFrom()"," (returns ",[15,7929,390],{}," instead).",[83,7932,7934],{"className":85,"code":7933,"language":87,"meta":88,"style":88},"// Pure enum: just named cases.\nenum Direction {\n    case North;\n    case South;\n}\nDirection::North;                      // an enum instance\n\n// Backed enum: each case has a scalar value, plus methods.\nenum Status: string {\n    case Active   = 'active';\n    case Archived = 'archived';\n\n    public function label(): string {  // enums can have methods\n        return ucfirst($this->value);\n    }\n}\n\nStatus::Active->value;      // 'active'\nStatus::Active->label();    // 'Active'\nStatus::from('archived');   // Status::Archived (throws if the value is unknown)\nStatus::tryFrom('nope');    // null (safe lookup)\nStatus::cases();            // [Status::Active, Status::Archived] (all cases)\n",[15,7935,7936,7941,7951,7960,7969,7973,7988,7992,7997,8010,8025,8039,8043,8064,8080,8084,8088,8092,8110,8129,8148,8167],{"__ignoreMap":88},[92,7937,7938],{"class":94,"line":95},[92,7939,7940],{"class":134},"// Pure enum: just named cases.\n",[92,7942,7943,7946,7949],{"class":94,"line":106},[92,7944,7945],{"class":98},"enum",[92,7947,7948],{"class":5161}," Direction",[92,7950,4695],{"class":119},[92,7952,7953,7955,7958],{"class":94,"line":113},[92,7954,4822],{"class":98},[92,7956,7957],{"class":102}," North",[92,7959,229],{"class":119},[92,7961,7962,7964,7967],{"class":94,"line":138},[92,7963,4822],{"class":98},[92,7965,7966],{"class":102}," South",[92,7968,229],{"class":119},[92,7970,7971],{"class":94,"line":143},[92,7972,4711],{"class":119},[92,7974,7975,7977,7979,7982,7985],{"class":94,"line":149},[92,7976,4085],{"class":102},[92,7978,6818],{"class":98},[92,7980,7981],{"class":102},"North",[92,7983,7984],{"class":119},";                      ",[92,7986,7987],{"class":134},"// an enum instance\n",[92,7989,7990],{"class":94,"line":155},[92,7991,110],{"emptyLinePlaceholder":109},[92,7993,7994],{"class":94,"line":161},[92,7995,7996],{"class":134},"// Backed enum: each case has a scalar value, plus methods.\n",[92,7998,7999,8001,8004,8006,8008],{"class":94,"line":166},[92,8000,7945],{"class":98},[92,8002,8003],{"class":5161}," Status",[92,8005,5185],{"class":98},[92,8007,5188],{"class":98},[92,8009,4695],{"class":119},[92,8011,8012,8014,8017,8020,8023],{"class":94,"line":187},[92,8013,4822],{"class":98},[92,8015,8016],{"class":102}," Active",[92,8018,8019],{"class":98},"   =",[92,8021,8022],{"class":171}," 'active'",[92,8024,229],{"class":119},[92,8026,8027,8029,8032,8034,8037],{"class":94,"line":217},[92,8028,4822],{"class":98},[92,8030,8031],{"class":102}," Archived",[92,8033,853],{"class":98},[92,8035,8036],{"class":171}," 'archived'",[92,8038,229],{"class":119},[92,8040,8041],{"class":94,"line":712},[92,8042,110],{"emptyLinePlaceholder":109},[92,8044,8045,8047,8049,8052,8054,8056,8058,8061],{"class":94,"line":730},[92,8046,6132],{"class":98},[92,8048,5659],{"class":98},[92,8050,8051],{"class":5161}," label",[92,8053,6042],{"class":119},[92,8055,5185],{"class":98},[92,8057,5188],{"class":98},[92,8059,8060],{"class":119}," {  ",[92,8062,8063],{"class":134},"// enums can have methods\n",[92,8065,8066,8068,8071,8073,8075,8077],{"class":94,"line":747},[92,8067,6236],{"class":98},[92,8069,8070],{"class":102}," ucfirst",[92,8072,120],{"class":119},[92,8074,6100],{"class":102},[92,8076,1996],{"class":98},[92,8078,8079],{"class":119},"value);\n",[92,8081,8082],{"class":94,"line":763},[92,8083,5104],{"class":119},[92,8085,8086],{"class":94,"line":780},[92,8087,4711],{"class":119},[92,8089,8090],{"class":94,"line":785},[92,8091,110],{"emptyLinePlaceholder":109},[92,8093,8094,8097,8099,8102,8104,8107],{"class":94,"line":2585},[92,8095,8096],{"class":102},"Status",[92,8098,6818],{"class":98},[92,8100,8101],{"class":102},"Active",[92,8103,1996],{"class":98},[92,8105,8106],{"class":119},"value;      ",[92,8108,8109],{"class":134},"// 'active'\n",[92,8111,8112,8114,8116,8118,8120,8123,8126],{"class":94,"line":2605},[92,8113,8096],{"class":102},[92,8115,6818],{"class":98},[92,8117,8101],{"class":102},[92,8119,1996],{"class":98},[92,8121,8122],{"class":5161},"label",[92,8124,8125],{"class":119},"();    ",[92,8127,8128],{"class":134},"// 'Active'\n",[92,8130,8131,8133,8135,8138,8140,8143,8145],{"class":94,"line":2634},[92,8132,8096],{"class":102},[92,8134,6818],{"class":98},[92,8136,8137],{"class":5161},"from",[92,8139,120],{"class":119},[92,8141,8142],{"class":171},"'archived'",[92,8144,131],{"class":119},[92,8146,8147],{"class":134},"// Status::Archived (throws if the value is unknown)\n",[92,8149,8150,8152,8154,8157,8159,8162,8164],{"class":94,"line":2651},[92,8151,8096],{"class":102},[92,8153,6818],{"class":98},[92,8155,8156],{"class":5161},"tryFrom",[92,8158,120],{"class":119},[92,8160,8161],{"class":171},"'nope'",[92,8163,2770],{"class":119},[92,8165,8166],{"class":134},"// null (safe lookup)\n",[92,8168,8169,8171,8173,8176,8179],{"class":94,"line":2671},[92,8170,8096],{"class":102},[92,8172,6818],{"class":98},[92,8174,8175],{"class":5161},"cases",[92,8177,8178],{"class":119},"();            ",[92,8180,8181],{"class":134},"// [Status::Active, Status::Archived] (all cases)\n",[242,8183,8185],{"id":8184},"magic-methods","Magic methods",[11,8187,8188,8189,8192,8193,529,8195,8197,8198,8201,8202,529,8205,8208,8209,529,8212,8215,8216,8218,8219,8222],{},"Magic methods are hooks named with a leading ",[15,8190,8191],{},"__"," that PHP calls automatically in specific situations. The ones you meet most are ",[15,8194,6471],{},[15,8196,6477],{}," (lifecycle), ",[15,8199,8200],{},"__toString"," (used when an object is treated as a string), ",[15,8203,8204],{},"__get",[15,8206,8207],{},"__set"," (intercept access to undefined properties), ",[15,8210,8211],{},"__call",[15,8213,8214],{},"__callStatic"," (intercept calls to undefined methods), ",[15,8217,5839],{}," (lets you call an object like a function), and ",[15,8220,8221],{},"__clone"," (customize copying). They are powerful for building expressive APIs but obscure control flow, so use them deliberately.",[83,8224,8226],{"className":85,"code":8225,"language":87,"meta":88,"style":88},"class Money {\n    public function __construct(private int $cents) {}\n\n    public function __toString(): string {          // echo/concatenation triggers this\n        return '$' . number_format($this->cents / 100, 2);\n    }\n}\necho new Money(1599);   // '$15.99'\n\nclass Multiplier {\n    public function __construct(private int $factor) {}\n    public function __invoke(int $n): int {          // makes the object callable\n        return $n * $this->factor;\n    }\n}\n$double = new Multiplier(2);\n$double(5);                       // 10  (the object is called like a function)\narray_map($double, [1, 2, 3]);   // [2, 4, 6]\n",[15,8227,8228,8236,8253,8257,8277,8309,8313,8317,8335,8339,8348,8365,8389,8404,8408,8412,8429,8441],{"__ignoreMap":88},[92,8229,8230,8232,8234],{"class":94,"line":95},[92,8231,6122],{"class":98},[92,8233,6702],{"class":5161},[92,8235,4695],{"class":119},[92,8237,8238,8240,8242,8244,8246,8248,8250],{"class":94,"line":106},[92,8239,6132],{"class":98},[92,8241,5659],{"class":98},[92,8243,6163],{"class":102},[92,8245,120],{"class":119},[92,8247,6335],{"class":98},[92,8249,5370],{"class":98},[92,8251,8252],{"class":119}," $cents) {}\n",[92,8254,8255],{"class":94,"line":113},[92,8256,110],{"emptyLinePlaceholder":109},[92,8258,8259,8261,8263,8266,8268,8270,8272,8274],{"class":94,"line":138},[92,8260,6132],{"class":98},[92,8262,5659],{"class":98},[92,8264,8265],{"class":102}," __toString",[92,8267,6042],{"class":119},[92,8269,5185],{"class":98},[92,8271,5188],{"class":98},[92,8273,7117],{"class":119},[92,8275,8276],{"class":134},"// echo/concatenation triggers this\n",[92,8278,8279,8281,8284,8286,8289,8291,8293,8295,8298,8300,8303,8305,8307],{"class":94,"line":143},[92,8280,6236],{"class":98},[92,8282,8283],{"class":171}," '$'",[92,8285,2108],{"class":98},[92,8287,8288],{"class":102}," number_format",[92,8290,120],{"class":119},[92,8292,6100],{"class":102},[92,8294,1996],{"class":98},[92,8296,8297],{"class":119},"cents ",[92,8299,529],{"class":98},[92,8301,8302],{"class":102}," 100",[92,8304,195],{"class":119},[92,8306,354],{"class":102},[92,8308,6289],{"class":119},[92,8310,8311],{"class":94,"line":149},[92,8312,5104],{"class":119},[92,8314,8315],{"class":94,"line":155},[92,8316,4711],{"class":119},[92,8318,8319,8321,8323,8325,8327,8330,8332],{"class":94,"line":161},[92,8320,60],{"class":102},[92,8322,6274],{"class":98},[92,8324,6702],{"class":102},[92,8326,120],{"class":119},[92,8328,8329],{"class":102},"1599",[92,8331,131],{"class":119},[92,8333,8334],{"class":134},"// '$15.99'\n",[92,8336,8337],{"class":94,"line":166},[92,8338,110],{"emptyLinePlaceholder":109},[92,8340,8341,8343,8346],{"class":94,"line":187},[92,8342,6122],{"class":98},[92,8344,8345],{"class":5161}," Multiplier",[92,8347,4695],{"class":119},[92,8349,8350,8352,8354,8356,8358,8360,8362],{"class":94,"line":217},[92,8351,6132],{"class":98},[92,8353,5659],{"class":98},[92,8355,6163],{"class":102},[92,8357,120],{"class":119},[92,8359,6335],{"class":98},[92,8361,5370],{"class":98},[92,8363,8364],{"class":119}," $factor) {}\n",[92,8366,8367,8369,8371,8374,8376,8378,8380,8382,8384,8386],{"class":94,"line":712},[92,8368,6132],{"class":98},[92,8370,5659],{"class":98},[92,8372,8373],{"class":102}," __invoke",[92,8375,120],{"class":119},[92,8377,370],{"class":98},[92,8379,5776],{"class":119},[92,8381,5185],{"class":98},[92,8383,5370],{"class":98},[92,8385,7117],{"class":119},[92,8387,8388],{"class":134},"// makes the object callable\n",[92,8390,8391,8393,8395,8397,8399,8401],{"class":94,"line":730},[92,8392,6236],{"class":98},[92,8394,5684],{"class":119},[92,8396,1959],{"class":98},[92,8398,6239],{"class":102},[92,8400,1996],{"class":98},[92,8402,8403],{"class":119},"factor;\n",[92,8405,8406],{"class":94,"line":747},[92,8407,5104],{"class":119},[92,8409,8410],{"class":94,"line":763},[92,8411,4711],{"class":119},[92,8413,8414,8417,8419,8421,8423,8425,8427],{"class":94,"line":780},[92,8415,8416],{"class":119},"$double ",[92,8418,126],{"class":98},[92,8420,6274],{"class":98},[92,8422,8345],{"class":102},[92,8424,120],{"class":119},[92,8426,354],{"class":102},[92,8428,6289],{"class":119},[92,8430,8431,8434,8436,8438],{"class":94,"line":785},[92,8432,8433],{"class":119},"$double(",[92,8435,1463],{"class":102},[92,8437,3995],{"class":119},[92,8439,8440],{"class":134},"// 10  (the object is called like a function)\n",[92,8442,8443,8445,8448,8450,8452,8454,8456,8458,8460],{"class":94,"line":2585},[92,8444,3322],{"class":102},[92,8446,8447],{"class":119},"($double, [",[92,8449,68],{"class":102},[92,8451,195],{"class":119},[92,8453,354],{"class":102},[92,8455,195],{"class":119},[92,8457,1448],{"class":102},[92,8459,5873],{"class":119},[92,8461,8462],{"class":134},"// [2, 4, 6]\n",[242,8464,8466],{"id":8465},"object-comparison-and-cloning","Object comparison and cloning",[11,8468,8469,8470,8472,8473,8475,8476,8479,8480,8483,8484,8486],{},"Objects are compared two ways: ",[15,8471,1344],{}," is true when two objects are the same class with equal properties, while ",[15,8474,1352],{}," is true only when both variables point to the ",[1511,8477,8478],{},"exact same instance",". Assigning an object copies a handle, not the object, so two variables share one instance; use the ",[15,8481,8482],{},"clone"," keyword to make a separate (shallow) copy, and define ",[15,8485,8221],{}," to deep-copy any nested objects.",[83,8488,8490],{"className":85,"code":8489,"language":87,"meta":88,"style":88},"$a = new Point(1, 2);\n$b = $a;             // $b is the SAME object as $a (a shared handle)\n$c = clone $a;       // $c is an independent copy\n\n$a === $b;           // true:  identical instance\n$a === $c;           // false: different instance\n$a == $c;            // true:  same class, equal property values\n\n$a->x = 99;\n$b->x;               // 99  (shared), but $c->x is still 1\n",[15,8491,8492,8512,8525,8541,8545,8557,8569,8581,8585,8600],{"__ignoreMap":88},[92,8493,8494,8496,8498,8500,8502,8504,8506,8508,8510],{"class":94,"line":95},[92,8495,321],{"class":119},[92,8497,126],{"class":98},[92,8499,6274],{"class":98},[92,8501,6589],{"class":102},[92,8503,120],{"class":119},[92,8505,68],{"class":102},[92,8507,195],{"class":119},[92,8509,354],{"class":102},[92,8511,6289],{"class":119},[92,8513,8514,8517,8519,8522],{"class":94,"line":106},[92,8515,8516],{"class":119},"$b ",[92,8518,126],{"class":98},[92,8520,8521],{"class":119}," $a;             ",[92,8523,8524],{"class":134},"// $b is the SAME object as $a (a shared handle)\n",[92,8526,8527,8530,8532,8535,8538],{"class":94,"line":113},[92,8528,8529],{"class":119},"$c ",[92,8531,126],{"class":98},[92,8533,8534],{"class":98}," clone",[92,8536,8537],{"class":119}," $a;       ",[92,8539,8540],{"class":134},"// $c is an independent copy\n",[92,8542,8543],{"class":94,"line":138},[92,8544,110],{"emptyLinePlaceholder":109},[92,8546,8547,8549,8551,8554],{"class":94,"line":143},[92,8548,321],{"class":119},[92,8550,1352],{"class":98},[92,8552,8553],{"class":119}," $b;           ",[92,8555,8556],{"class":134},"// true:  identical instance\n",[92,8558,8559,8561,8563,8566],{"class":94,"line":149},[92,8560,321],{"class":119},[92,8562,1352],{"class":98},[92,8564,8565],{"class":119}," $c;           ",[92,8567,8568],{"class":134},"// false: different instance\n",[92,8570,8571,8573,8575,8578],{"class":94,"line":155},[92,8572,321],{"class":119},[92,8574,1344],{"class":98},[92,8576,8577],{"class":119}," $c;            ",[92,8579,8580],{"class":134},"// true:  same class, equal property values\n",[92,8582,8583],{"class":94,"line":161},[92,8584,110],{"emptyLinePlaceholder":109},[92,8586,8587,8589,8591,8593,8595,8598],{"class":94,"line":166},[92,8588,7878],{"class":119},[92,8590,1996],{"class":98},[92,8592,6548],{"class":119},[92,8594,126],{"class":98},[92,8596,8597],{"class":102}," 99",[92,8599,229],{"class":119},[92,8601,8602,8605,8607,8610],{"class":94,"line":187},[92,8603,8604],{"class":119},"$b",[92,8606,1996],{"class":98},[92,8608,8609],{"class":119},"x;               ",[92,8611,8612],{"class":134},"// 99  (shared), but $c->x is still 1\n",[242,8614,8616],{"id":8615},"namespaces","Namespaces",[11,8618,8619,8620,8623,8624,8626,8627,8629,8630,8633,8634,8637,8638,6339,8641,81],{},"A namespace groups classes to prevent name collisions across a large codebase or between packages, declared with ",[15,8621,8622],{},"namespace"," at the top of a file. You pull a class in by its full name with ",[15,8625,5612],{},", optionally aliasing it with ",[15,8628,4497],{},", and Composer's autoloader maps namespaces to file paths so you never write manual ",[15,8631,8632],{},"require"," statements. A leading ",[15,8635,8636],{},"\\"," means the global namespace, which is why you occasionally see ",[15,8639,8640],{},"\\DateTime",[15,8642,8643],{},"\\strlen",[83,8645,8647],{"className":85,"code":8646,"language":87,"meta":88,"style":88},"namespace App\\Models;\n\nuse App\\Support\\Str;\nuse App\\Services\\Mailer as Mail;   // alias to avoid a clash\n\nclass User {\n    public function greeting(): string {\n        return Str::title('hello');   // resolved via the `use` above\n    }\n}\n",[15,8648,8649,8658,8662,8671,8689,8693,8702,8719,8740,8744],{"__ignoreMap":88},[92,8650,8651,8653,8656],{"class":94,"line":95},[92,8652,8622],{"class":98},[92,8654,8655],{"class":5161}," App\\Models",[92,8657,229],{"class":119},[92,8659,8660],{"class":94,"line":106},[92,8661,110],{"emptyLinePlaceholder":109},[92,8663,8664,8666,8669],{"class":94,"line":113},[92,8665,5612],{"class":98},[92,8667,8668],{"class":102}," App\\Support\\Str",[92,8670,229],{"class":119},[92,8672,8673,8675,8678,8681,8684,8686],{"class":94,"line":138},[92,8674,5612],{"class":98},[92,8676,8677],{"class":102}," App\\Services\\Mailer",[92,8679,8680],{"class":98}," as",[92,8682,8683],{"class":5161}," Mail",[92,8685,309],{"class":119},[92,8687,8688],{"class":134},"// alias to avoid a clash\n",[92,8690,8691],{"class":94,"line":143},[92,8692,110],{"emptyLinePlaceholder":109},[92,8694,8695,8697,8700],{"class":94,"line":149},[92,8696,6122],{"class":98},[92,8698,8699],{"class":5161}," User",[92,8701,4695],{"class":119},[92,8703,8704,8706,8708,8711,8713,8715,8717],{"class":94,"line":155},[92,8705,6132],{"class":98},[92,8707,5659],{"class":98},[92,8709,8710],{"class":5161}," greeting",[92,8712,6042],{"class":119},[92,8714,5185],{"class":98},[92,8716,5188],{"class":98},[92,8718,4695],{"class":119},[92,8720,8721,8723,8726,8728,8731,8733,8735,8737],{"class":94,"line":161},[92,8722,6236],{"class":98},[92,8724,8725],{"class":102}," Str",[92,8727,6818],{"class":98},[92,8729,8730],{"class":5161},"title",[92,8732,120],{"class":119},[92,8734,2315],{"class":171},[92,8736,131],{"class":119},[92,8738,8739],{"class":134},"// resolved via the `use` above\n",[92,8741,8742],{"class":94,"line":166},[92,8743,5104],{"class":119},[92,8745,8746],{"class":94,"line":187},[92,8747,4711],{"class":119},[39,8749,8751],{"id":8750},"error-and-exception-handling","Error and Exception Handling",[242,8753,8755],{"id":8754},"try-catch-finally","try, catch, finally",[11,8757,8758,8759,8762,8763,8766,8767,8770,8771,8773],{},"PHP handles runtime problems with exceptions: code that might fail goes in a ",[15,8760,8761],{},"try"," block, ",[15,8764,8765],{},"catch"," handles a thrown exception by type, and an optional ",[15,8768,8769],{},"finally"," block runs no matter what (success, caught exception, or even an uncaught one), which is where you release resources. You can catch several unrelated types in one block with the ",[15,8772,1810],{}," union syntax, and each exception carries a message, a code, and a link to whatever caused it.",[83,8775,8777],{"className":85,"code":8776,"language":87,"meta":88,"style":88},"try {\n    $data = json_decode($raw, true, flags: JSON_THROW_ON_ERROR);\n    process($data);\n} catch (JsonException | ValidationException $e) {   // catch multiple types\n    echo $e->getMessage();       // the human-readable message\n    echo $e->getCode();          // an optional numeric code\n    throw new RuntimeException('processing failed', previous: $e);  // wrap and rethrow\n} finally {\n    releaseLock();               // always runs\n}\n",[15,8778,8779,8785,8812,8820,8843,8861,8878,8903,8911,8922],{"__ignoreMap":88},[92,8780,8781,8783],{"class":94,"line":95},[92,8782,8761],{"class":98},[92,8784,4695],{"class":119},[92,8786,8787,8790,8792,8795,8798,8800,8802,8805,8807,8810],{"class":94,"line":106},[92,8788,8789],{"class":119},"    $data ",[92,8791,126],{"class":98},[92,8793,8794],{"class":102}," json_decode",[92,8796,8797],{"class":119},"($raw, ",[92,8799,474],{"class":102},[92,8801,195],{"class":119},[92,8803,8804],{"class":5161},"flags",[92,8806,5263],{"class":119},[92,8808,8809],{"class":102},"JSON_THROW_ON_ERROR",[92,8811,6289],{"class":119},[92,8813,8814,8817],{"class":94,"line":113},[92,8815,8816],{"class":5161},"    process",[92,8818,8819],{"class":119},"($data);\n",[92,8821,8822,8824,8826,8828,8831,8834,8837,8840],{"class":94,"line":138},[92,8823,4664],{"class":119},[92,8825,8765],{"class":98},[92,8827,3559],{"class":119},[92,8829,8830],{"class":102},"JsonException",[92,8832,8833],{"class":119}," | ",[92,8835,8836],{"class":102},"ValidationException",[92,8838,8839],{"class":119}," $e) {   ",[92,8841,8842],{"class":134},"// catch multiple types\n",[92,8844,8845,8847,8850,8852,8855,8858],{"class":94,"line":143},[92,8846,5314],{"class":102},[92,8848,8849],{"class":119}," $e",[92,8851,1996],{"class":98},[92,8853,8854],{"class":5161},"getMessage",[92,8856,8857],{"class":119},"();       ",[92,8859,8860],{"class":134},"// the human-readable message\n",[92,8862,8863,8865,8867,8869,8872,8875],{"class":94,"line":149},[92,8864,5314],{"class":102},[92,8866,8849],{"class":119},[92,8868,1996],{"class":98},[92,8870,8871],{"class":5161},"getCode",[92,8873,8874],{"class":119},"();          ",[92,8876,8877],{"class":134},"// an optional numeric code\n",[92,8879,8880,8883,8885,8887,8889,8892,8894,8897,8900],{"class":94,"line":155},[92,8881,8882],{"class":98},"    throw",[92,8884,6274],{"class":98},[92,8886,1945],{"class":102},[92,8888,120],{"class":119},[92,8890,8891],{"class":171},"'processing failed'",[92,8893,195],{"class":119},[92,8895,8896],{"class":5161},"previous",[92,8898,8899],{"class":119},": $e);  ",[92,8901,8902],{"class":134},"// wrap and rethrow\n",[92,8904,8905,8907,8909],{"class":94,"line":161},[92,8906,4664],{"class":119},[92,8908,8769],{"class":98},[92,8910,4695],{"class":119},[92,8912,8913,8916,8919],{"class":94,"line":166},[92,8914,8915],{"class":5161},"    releaseLock",[92,8917,8918],{"class":119},"();               ",[92,8920,8921],{"class":134},"// always runs\n",[92,8923,8924],{"class":94,"line":187},[92,8925,4711],{"class":119},[242,8927,8929],{"id":8928},"throwing-exceptions","Throwing exceptions",[11,8931,8932,8933,8936,8937,8939,8940,8943,8944,6339,8946,8948],{},"You raise an exception with ",[15,8934,8935],{},"throw",", passing a message and optionally a code and a previous exception for chaining. Since PHP 8.0, ",[15,8938,8935],{}," is an ",[1511,8941,8942],{},"expression",", so it works inline on the right of ",[15,8945,1733],{},[15,8947,1713],{},", which is a clean way to fail fast on a missing value.",[83,8950,8952],{"className":85,"code":8951,"language":87,"meta":88,"style":88},"function findUser(int $id): User {\n    return $userRepository->get($id)\n        ?? throw new NotFoundException(\"no user with id $id\");   // throw as an expression\n}\n",[15,8953,8954,8974,8989,9017],{"__ignoreMap":88},[92,8955,8956,8958,8961,8963,8965,8968,8970,8972],{"class":94,"line":95},[92,8957,3556],{"class":98},[92,8959,8960],{"class":5161}," findUser",[92,8962,120],{"class":119},[92,8964,370],{"class":98},[92,8966,8967],{"class":119}," $id)",[92,8969,5185],{"class":98},[92,8971,8699],{"class":102},[92,8973,4695],{"class":119},[92,8975,8976,8978,8981,8983,8986],{"class":94,"line":106},[92,8977,5195],{"class":98},[92,8979,8980],{"class":119}," $userRepository",[92,8982,1996],{"class":98},[92,8984,8985],{"class":5161},"get",[92,8987,8988],{"class":119},"($id)\n",[92,8990,8991,8994,8997,8999,9002,9004,9007,9010,9012,9014],{"class":94,"line":113},[92,8992,8993],{"class":98},"        ??",[92,8995,8996],{"class":98}," throw",[92,8998,6274],{"class":98},[92,9000,9001],{"class":102}," NotFoundException",[92,9003,120],{"class":119},[92,9005,9006],{"class":171},"\"no user with id ",[92,9008,9009],{"class":119},"$id",[92,9011,178],{"class":171},[92,9013,131],{"class":119},[92,9015,9016],{"class":134},"// throw as an expression\n",[92,9018,9019],{"class":94,"line":138},[92,9020,4711],{"class":119},[242,9022,9024],{"id":9023},"the-exception-hierarchy","The exception hierarchy",[11,9026,9027,9028,9031,9032,9035,9036,9039,9040,9042,9043,9046,9047,195,9049,1375,9051,9053,9054,9057,9058,9061,9062,9064,9065,9067,9068,8939,9070,9072,9073,9075,9076,9078],{},"Every throwable in PHP implements the ",[15,9029,9030],{},"Throwable"," interface, which has two branches: ",[15,9033,9034],{},"Exception"," is the base for application-level problems you throw and catch, while ",[15,9037,9038],{},"Error"," is for engine-level failures such as ",[15,9041,1150],{}," (a bad argument type), ",[15,9044,9045],{},"DivisionByZeroError"," (from ",[15,9048,1249],{},[15,9050,1178],{},[15,9052,529],{}," by zero in PHP 8), and ",[15,9055,9056],{},"ParseError",". The practical consequence is that ",[15,9059,9060],{},"catch (Exception $e)"," will ",[1511,9063,5608],{}," catch a ",[15,9066,1150],{},", because a ",[15,9069,1150],{},[15,9071,9038],{},", not an ",[15,9074,9034],{},"; catch ",[15,9077,9030],{}," only when you truly want to trap everything, including engine errors.",[11,9080,9081],{},[3108,9082],{"alt":9083,"src":9084},"PHP throwable hierarchy: Throwable splits into Error and Exception branches","/post-images/php-syntax-recap/php-throwable-hierarchy.png",[242,9086,9088],{"id":9087},"custom-exceptions","Custom exceptions",[11,9090,9091,9092,9094,9095,6339,9098,9101,9102,9105,9106,9108],{},"You create a domain-specific exception by extending ",[15,9093,9034],{}," (or a more specific SPL exception like ",[15,9096,9097],{},"InvalidArgumentException",[15,9099,9100],{},"RuntimeException","), which lets callers catch exactly the failure they care about. The SPL exceptions already model common cases: ",[15,9103,9104],{},"LogicException"," for bugs that should be fixed in code, and ",[15,9107,9100],{}," for problems that only appear at runtime.",[83,9110,9112],{"className":85,"code":9111,"language":87,"meta":88,"style":88},"class InsufficientFundsException extends RuntimeException {}\n\nfunction withdraw(Account $a, int $amount): void {\n    if ($amount > $a->balance) {\n        throw new InsufficientFundsException(\"short by \" . ($amount - $a->balance));\n    }\n    // ...\n}\n\ntry {\n    withdraw($account, 500);\n} catch (InsufficientFundsException $e) {   // catch precisely this failure\n    notifyUser($e->getMessage());\n}\n",[15,9113,9114,9128,9132,9157,9175,9202,9206,9211,9215,9219,9225,9238,9254,9269],{"__ignoreMap":88},[92,9115,9116,9118,9121,9123,9125],{"class":94,"line":95},[92,9117,6122],{"class":98},[92,9119,9120],{"class":5161}," InsufficientFundsException",[92,9122,7096],{"class":98},[92,9124,1945],{"class":102},[92,9126,9127],{"class":119}," {}\n",[92,9129,9130],{"class":94,"line":106},[92,9131,110],{"emptyLinePlaceholder":109},[92,9133,9134,9136,9139,9141,9144,9147,9149,9151,9153,9155],{"class":94,"line":113},[92,9135,3556],{"class":98},[92,9137,9138],{"class":5161}," withdraw",[92,9140,120],{"class":119},[92,9142,9143],{"class":102},"Account",[92,9145,9146],{"class":119}," $a, ",[92,9148,370],{"class":98},[92,9150,6396],{"class":119},[92,9152,5185],{"class":98},[92,9154,5303],{"class":98},[92,9156,4695],{"class":119},[92,9158,9159,9162,9165,9167,9170,9172],{"class":94,"line":138},[92,9160,9161],{"class":98},"    if",[92,9163,9164],{"class":119}," ($amount ",[92,9166,1599],{"class":98},[92,9168,9169],{"class":119}," $a",[92,9171,1996],{"class":98},[92,9173,9174],{"class":119},"balance) {\n",[92,9176,9177,9180,9182,9184,9186,9189,9191,9193,9195,9197,9199],{"class":94,"line":143},[92,9178,9179],{"class":98},"        throw",[92,9181,6274],{"class":98},[92,9183,9120],{"class":102},[92,9185,120],{"class":119},[92,9187,9188],{"class":171},"\"short by \"",[92,9190,2108],{"class":98},[92,9192,9164],{"class":119},[92,9194,1966],{"class":98},[92,9196,9169],{"class":119},[92,9198,1996],{"class":98},[92,9200,9201],{"class":119},"balance));\n",[92,9203,9204],{"class":94,"line":149},[92,9205,5104],{"class":119},[92,9207,9208],{"class":94,"line":155},[92,9209,9210],{"class":134},"    // ...\n",[92,9212,9213],{"class":94,"line":161},[92,9214,4711],{"class":119},[92,9216,9217],{"class":94,"line":166},[92,9218,110],{"emptyLinePlaceholder":109},[92,9220,9221,9223],{"class":94,"line":187},[92,9222,8761],{"class":98},[92,9224,4695],{"class":119},[92,9226,9227,9230,9233,9236],{"class":94,"line":217},[92,9228,9229],{"class":5161},"    withdraw",[92,9231,9232],{"class":119},"($account, ",[92,9234,9235],{"class":102},"500",[92,9237,6289],{"class":119},[92,9239,9240,9242,9244,9246,9249,9251],{"class":94,"line":712},[92,9241,4664],{"class":119},[92,9243,8765],{"class":98},[92,9245,3559],{"class":119},[92,9247,9248],{"class":102},"InsufficientFundsException",[92,9250,8839],{"class":119},[92,9252,9253],{"class":134},"// catch precisely this failure\n",[92,9255,9256,9259,9262,9264,9266],{"class":94,"line":730},[92,9257,9258],{"class":5161},"    notifyUser",[92,9260,9261],{"class":119},"($e",[92,9263,1996],{"class":98},[92,9265,8854],{"class":5161},[92,9267,9268],{"class":119},"());\n",[92,9270,9271],{"class":94,"line":747},[92,9272,4711],{"class":119},[11,9274,9275,9276,9279,9280,9282,9283,9285,9286,9288],{},"Catch the specific types you can actually handle rather than a blanket ",[15,9277,9278],{},"\\Exception",", remember that engine failures are ",[15,9281,9038],{}," and not ",[15,9284,9034],{},", and treat the ",[15,9287,1830],{}," error-suppression operator as a smell to remove rather than a tool to reach for.",[39,9290,9292],{"id":9291},"standard-library-essentials","Standard Library Essentials",[242,9294,9296],{"id":9295},"debugging-output","Debugging output",[11,9298,9299,9300,9303,9304,9307,9308,9311,9312,9314,9315,6339,9318,9321],{},"When you need to see what a value actually holds, three functions do the job at different levels of detail. ",[15,9301,9302],{},"var_dump()"," prints the type and value (and recurses into arrays and objects), which is the one you reach for while debugging; ",[15,9305,9306],{},"print_r()"," prints a compact human-readable form; and ",[15,9309,9310],{},"var_export()"," prints valid PHP you could paste back into code. Pass ",[15,9313,474],{}," as the second argument to ",[15,9316,9317],{},"print_r",[15,9319,9320],{},"var_export"," to get a string back instead of printing.",[83,9323,9325],{"className":85,"code":9324,"language":87,"meta":88,"style":88},"$data = ['name' => 'Ada', 'roles' => ['admin', 'editor']];\n\nvar_dump($data);\n// array(2) { [\"name\"]=> string(3) \"Ada\" [\"roles\"]=> array(2) { [0]=> string(5) \"admin\" ... } }\n\nprint_r($data);\n// Array ( [name] => Ada [roles] => Array ( [0] => admin [1] => editor ) )\n\n$asString = print_r($data, true);   // capture the output instead of printing it\n",[15,9326,9327,9362,9366,9373,9378,9382,9388,9393,9397],{"__ignoreMap":88},[92,9328,9329,9332,9334,9336,9338,9340,9342,9344,9347,9349,9351,9354,9356,9359],{"class":94,"line":95},[92,9330,9331],{"class":119},"$data ",[92,9333,126],{"class":98},[92,9335,347],{"class":119},[92,9337,1016],{"class":171},[92,9339,1019],{"class":98},[92,9341,271],{"class":171},[92,9343,195],{"class":119},[92,9345,9346],{"class":171},"'roles'",[92,9348,1019],{"class":98},[92,9350,347],{"class":119},[92,9352,9353],{"class":171},"'admin'",[92,9355,195],{"class":119},[92,9357,9358],{"class":171},"'editor'",[92,9360,9361],{"class":119},"]];\n",[92,9363,9364],{"class":94,"line":106},[92,9365,110],{"emptyLinePlaceholder":109},[92,9367,9368,9371],{"class":94,"line":113},[92,9369,9370],{"class":102},"var_dump",[92,9372,8819],{"class":119},[92,9374,9375],{"class":94,"line":138},[92,9376,9377],{"class":134},"// array(2) { [\"name\"]=> string(3) \"Ada\" [\"roles\"]=> array(2) { [0]=> string(5) \"admin\" ... } }\n",[92,9379,9380],{"class":94,"line":143},[92,9381,110],{"emptyLinePlaceholder":109},[92,9383,9384,9386],{"class":94,"line":149},[92,9385,9317],{"class":102},[92,9387,8819],{"class":119},[92,9389,9390],{"class":94,"line":155},[92,9391,9392],{"class":134},"// Array ( [name] => Ada [roles] => Array ( [0] => admin [1] => editor ) )\n",[92,9394,9395],{"class":94,"line":161},[92,9396,110],{"emptyLinePlaceholder":109},[92,9398,9399,9402,9404,9407,9410,9412,9414],{"class":94,"line":166},[92,9400,9401],{"class":119},"$asString ",[92,9403,126],{"class":98},[92,9405,9406],{"class":102}," print_r",[92,9408,9409],{"class":119},"($data, ",[92,9411,474],{"class":102},[92,9413,131],{"class":119},[92,9415,9416],{"class":134},"// capture the output instead of printing it\n",[242,9418,9420],{"id":9419},"math","Math",[11,9422,9423,9424,9426,9427,9430,9431,529,9433,9435,9436,9439,9440,9443],{},"The math functions cover the usual ground, with ",[15,9425,1249],{}," for integer division, ",[15,9428,9429],{},"fmod"," for a floating-point remainder, and both ",[15,9432,4036],{},[15,9434,4042],{}," accepting either several arguments or a single array. For random numbers, prefer ",[15,9437,9438],{},"random_int()"," over ",[15,9441,9442],{},"rand()"," when the value must be unpredictable, since it is cryptographically secure.",[83,9445,9447],{"className":85,"code":9446,"language":87,"meta":88,"style":88},"abs(-5);              // 5\nceil(4.1);            // 5.0  (always rounds up)\nfloor(4.9);           // 4.0  (always rounds down)\nround(3.14159, 2);    // 3.14 (round to 2 decimals)\nsqrt(144);            // 12.0\n2 ** 10;              // 1024 (or pow(2, 10))\nintdiv(17, 5);        // 3\n17 % 5;               // 2\nfmod(7.5, 2);         // 1.5  (float remainder)\nmax(3, 7, 2);         // 7    (max([3, 7, 2]) also works)\nmin([3, 7, 2]);       // 2\nrandom_int(1, 6);     // a secure random int in [1, 6]\nnumber_format(1234.5, 2); // '1,234.50'\n",[15,9448,9449,9465,9480,9495,9514,9529,9543,9561,9574,9593,9614,9634,9652],{"__ignoreMap":88},[92,9450,9451,9454,9456,9458,9460,9462],{"class":94,"line":95},[92,9452,9453],{"class":102},"abs",[92,9455,120],{"class":119},[92,9457,1966],{"class":98},[92,9459,1463],{"class":102},[92,9461,2414],{"class":119},[92,9463,9464],{"class":134},"// 5\n",[92,9466,9467,9470,9472,9475,9477],{"class":94,"line":106},[92,9468,9469],{"class":102},"ceil",[92,9471,120],{"class":119},[92,9473,9474],{"class":102},"4.1",[92,9476,2441],{"class":119},[92,9478,9479],{"class":134},"// 5.0  (always rounds up)\n",[92,9481,9482,9485,9487,9490,9492],{"class":94,"line":113},[92,9483,9484],{"class":102},"floor",[92,9486,120],{"class":119},[92,9488,9489],{"class":102},"4.9",[92,9491,2378],{"class":119},[92,9493,9494],{"class":134},"// 4.0  (always rounds down)\n",[92,9496,9497,9500,9502,9505,9507,9509,9511],{"class":94,"line":138},[92,9498,9499],{"class":102},"round",[92,9501,120],{"class":119},[92,9503,9504],{"class":102},"3.14159",[92,9506,195],{"class":119},[92,9508,354],{"class":102},[92,9510,2770],{"class":119},[92,9512,9513],{"class":134},"// 3.14 (round to 2 decimals)\n",[92,9515,9516,9519,9521,9524,9526],{"class":94,"line":143},[92,9517,9518],{"class":102},"sqrt",[92,9520,120],{"class":119},[92,9522,9523],{"class":102},"144",[92,9525,2441],{"class":119},[92,9527,9528],{"class":134},"// 12.0\n",[92,9530,9531,9533,9535,9537,9540],{"class":94,"line":149},[92,9532,354],{"class":102},[92,9534,1283],{"class":98},[92,9536,1286],{"class":102},[92,9538,9539],{"class":119},";              ",[92,9541,9542],{"class":134},"// 1024 (or pow(2, 10))\n",[92,9544,9545,9547,9549,9552,9554,9556,9558],{"class":94,"line":155},[92,9546,1249],{"class":102},[92,9548,120],{"class":119},[92,9550,9551],{"class":102},"17",[92,9553,195],{"class":119},[92,9555,1463],{"class":102},[92,9557,433],{"class":119},[92,9559,9560],{"class":134},"// 3\n",[92,9562,9563,9565,9567,9569,9572],{"class":94,"line":161},[92,9564,9551],{"class":102},[92,9566,1269],{"class":98},[92,9568,1315],{"class":102},[92,9570,9571],{"class":119},";               ",[92,9573,2582],{"class":134},[92,9575,9576,9578,9580,9583,9585,9587,9590],{"class":94,"line":166},[92,9577,9429],{"class":102},[92,9579,120],{"class":119},[92,9581,9582],{"class":102},"7.5",[92,9584,195],{"class":119},[92,9586,354],{"class":102},[92,9588,9589],{"class":119},");         ",[92,9591,9592],{"class":134},"// 1.5  (float remainder)\n",[92,9594,9595,9597,9599,9601,9603,9605,9607,9609,9611],{"class":94,"line":187},[92,9596,4036],{"class":102},[92,9598,120],{"class":119},[92,9600,1448],{"class":102},[92,9602,195],{"class":119},[92,9604,1205],{"class":102},[92,9606,195],{"class":119},[92,9608,354],{"class":102},[92,9610,9589],{"class":119},[92,9612,9613],{"class":134},"// 7    (max([3, 7, 2]) also works)\n",[92,9615,9616,9618,9620,9622,9624,9626,9628,9630,9632],{"class":94,"line":217},[92,9617,4042],{"class":102},[92,9619,486],{"class":119},[92,9621,1448],{"class":102},[92,9623,195],{"class":119},[92,9625,1205],{"class":102},[92,9627,195],{"class":119},[92,9629,354],{"class":102},[92,9631,627],{"class":119},[92,9633,2582],{"class":134},[92,9635,9636,9639,9641,9643,9645,9647,9649],{"class":94,"line":712},[92,9637,9638],{"class":5161},"random_int",[92,9640,120],{"class":119},[92,9642,68],{"class":102},[92,9644,195],{"class":119},[92,9646,1235],{"class":102},[92,9648,599],{"class":119},[92,9650,9651],{"class":134},"// a secure random int in [1, 6]\n",[92,9653,9654,9656,9658,9661,9663,9665,9667],{"class":94,"line":730},[92,9655,2758],{"class":102},[92,9657,120],{"class":119},[92,9659,9660],{"class":102},"1234.5",[92,9662,195],{"class":119},[92,9664,354],{"class":102},[92,9666,653],{"class":119},[92,9668,9669],{"class":134},"// '1,234.50'\n",[242,9671,9673],{"id":9672},"json","JSON",[11,9675,9676,9679,9680,9683,9684,9687,9688,9690,9691,9694,9695,9697,9698,9700,9701,9703,9704,81],{},[15,9677,9678],{},"json_encode()"," turns a PHP value into a JSON string and ",[15,9681,9682],{},"json_decode()"," parses one back. The important argument is the second parameter of ",[15,9685,9686],{},"json_decode",": pass ",[15,9689,474],{}," to get associative arrays, or omit it to get ",[15,9692,9693],{},"stdClass"," objects (accessed with ",[15,9696,1996],{},"). Add the ",[15,9699,8809],{}," flag so malformed input raises a ",[15,9702,8830],{}," instead of quietly returning ",[15,9705,390],{},[83,9707,9709],{"className":85,"code":9708,"language":87,"meta":88,"style":88},"$json = json_encode(['name' => 'Ada', 'tags' => ['a', 'b']]);\n// '{\"name\":\"Ada\",\"tags\":[\"a\",\"b\"]}'\n\n$asArray  = json_decode($json, true);   // ['name' => 'Ada', 'tags' => ['a', 'b']]\n$asObject = json_decode($json);         // stdClass; access with $asObject->name\n\necho json_encode($data, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR);  // formatted + safe\n",[15,9710,9711,9747,9752,9756,9775,9790,9794],{"__ignoreMap":88},[92,9712,9713,9716,9718,9721,9723,9725,9727,9729,9731,9734,9736,9738,9740,9742,9744],{"class":94,"line":95},[92,9714,9715],{"class":119},"$json ",[92,9717,126],{"class":98},[92,9719,9720],{"class":102}," json_encode",[92,9722,486],{"class":119},[92,9724,1016],{"class":171},[92,9726,1019],{"class":98},[92,9728,271],{"class":171},[92,9730,195],{"class":119},[92,9732,9733],{"class":171},"'tags'",[92,9735,1019],{"class":98},[92,9737,347],{"class":119},[92,9739,1844],{"class":171},[92,9741,195],{"class":119},[92,9743,198],{"class":171},[92,9745,9746],{"class":119},"]]);\n",[92,9748,9749],{"class":94,"line":106},[92,9750,9751],{"class":134},"// '{\"name\":\"Ada\",\"tags\":[\"a\",\"b\"]}'\n",[92,9753,9754],{"class":94,"line":113},[92,9755,110],{"emptyLinePlaceholder":109},[92,9757,9758,9761,9763,9765,9768,9770,9772],{"class":94,"line":138},[92,9759,9760],{"class":119},"$asArray  ",[92,9762,126],{"class":98},[92,9764,8794],{"class":102},[92,9766,9767],{"class":119},"($json, ",[92,9769,474],{"class":102},[92,9771,131],{"class":119},[92,9773,9774],{"class":134},"// ['name' => 'Ada', 'tags' => ['a', 'b']]\n",[92,9776,9777,9780,9782,9784,9787],{"class":94,"line":143},[92,9778,9779],{"class":119},"$asObject ",[92,9781,126],{"class":98},[92,9783,8794],{"class":102},[92,9785,9786],{"class":119},"($json);         ",[92,9788,9789],{"class":134},"// stdClass; access with $asObject->name\n",[92,9791,9792],{"class":94,"line":149},[92,9793,110],{"emptyLinePlaceholder":109},[92,9795,9796,9798,9800,9802,9805,9807,9810,9812],{"class":94,"line":155},[92,9797,60],{"class":102},[92,9799,9720],{"class":102},[92,9801,9409],{"class":119},[92,9803,9804],{"class":102},"JSON_PRETTY_PRINT",[92,9806,1909],{"class":98},[92,9808,9809],{"class":102}," JSON_THROW_ON_ERROR",[92,9811,800],{"class":119},[92,9813,9814],{"class":134},"// formatted + safe\n",[242,9816,9818],{"id":9817},"dates-and-times","Dates and times",[11,9820,9821,9822,9825,9826,9829,9830,9833,9834,9837],{},"For simple formatting, ",[15,9823,9824],{},"date()"," turns the current (or a given) timestamp into a string, and ",[15,9827,9828],{},"time()"," gives the current Unix timestamp. For real date arithmetic, use the ",[15,9831,9832],{},"DateTime"," classes; prefer ",[15,9835,9836],{},"DateTimeImmutable",", whose methods return a new object instead of mutating the original, which avoids a whole category of aliasing bugs.",[83,9839,9841],{"className":85,"code":9840,"language":87,"meta":88,"style":88},"date('Y-m-d');                     // e.g. '2026-08-25'\ntime();                            // current Unix timestamp (seconds)\nstrtotime('+1 week');              // a timestamp one week from now\n\n$start = new DateTimeImmutable('2026-08-25');\n$end   = $start->modify('+10 days');   // returns a NEW object; $start is unchanged\n$end->format('Y-m-d');                 // '2026-09-04'\n$start->diff($end)->days;              // 10\n",[15,9842,9843,9859,9870,9885,9889,9908,9933,9952],{"__ignoreMap":88},[92,9844,9845,9848,9850,9853,9856],{"class":94,"line":95},[92,9846,9847],{"class":102},"date",[92,9849,120],{"class":119},[92,9851,9852],{"class":171},"'Y-m-d'",[92,9854,9855],{"class":119},");                     ",[92,9857,9858],{"class":134},"// e.g. '2026-08-25'\n",[92,9860,9861,9864,9867],{"class":94,"line":106},[92,9862,9863],{"class":102},"time",[92,9865,9866],{"class":119},"();                            ",[92,9868,9869],{"class":134},"// current Unix timestamp (seconds)\n",[92,9871,9872,9875,9877,9880,9882],{"class":94,"line":113},[92,9873,9874],{"class":102},"strtotime",[92,9876,120],{"class":119},[92,9878,9879],{"class":171},"'+1 week'",[92,9881,2414],{"class":119},[92,9883,9884],{"class":134},"// a timestamp one week from now\n",[92,9886,9887],{"class":94,"line":138},[92,9888,110],{"emptyLinePlaceholder":109},[92,9890,9891,9894,9896,9898,9901,9903,9906],{"class":94,"line":143},[92,9892,9893],{"class":119},"$start ",[92,9895,126],{"class":98},[92,9897,6274],{"class":98},[92,9899,9900],{"class":102}," DateTimeImmutable",[92,9902,120],{"class":119},[92,9904,9905],{"class":171},"'2026-08-25'",[92,9907,6289],{"class":119},[92,9909,9910,9913,9915,9918,9920,9923,9925,9928,9930],{"class":94,"line":149},[92,9911,9912],{"class":119},"$end   ",[92,9914,126],{"class":98},[92,9916,9917],{"class":119}," $start",[92,9919,1996],{"class":98},[92,9921,9922],{"class":5161},"modify",[92,9924,120],{"class":119},[92,9926,9927],{"class":171},"'+10 days'",[92,9929,131],{"class":119},[92,9931,9932],{"class":134},"// returns a NEW object; $start is unchanged\n",[92,9934,9935,9938,9940,9943,9945,9947,9949],{"class":94,"line":155},[92,9936,9937],{"class":119},"$end",[92,9939,1996],{"class":98},[92,9941,9942],{"class":5161},"format",[92,9944,120],{"class":119},[92,9946,9852],{"class":171},[92,9948,2333],{"class":119},[92,9950,9951],{"class":134},"// '2026-09-04'\n",[92,9953,9954,9957,9959,9962,9965,9967,9970],{"class":94,"line":161},[92,9955,9956],{"class":119},"$start",[92,9958,1996],{"class":98},[92,9960,9961],{"class":5161},"diff",[92,9963,9964],{"class":119},"($end)",[92,9966,1996],{"class":98},[92,9968,9969],{"class":119},"days;              ",[92,9971,1215],{"class":134},[242,9973,9975],{"id":9974},"regular-expressions","Regular expressions",[11,9977,9978,9979,9982,9983,9985,9986,9989,9990,195,9992,1375,9994,975,9996,9999,10000,10003,10004,10007],{},"PHP's regex functions are the ",[15,9980,9981],{},"preg_*"," family, using PCRE syntax with delimiters (usually ",[15,9984,529],{},") around the pattern. ",[15,9987,9988],{},"preg_match"," fills an output array with the whole match and each captured group and returns ",[15,9991,68],{},[15,9993,554],{},[15,9995,2300],{},[15,9997,9998],{},"preg_match_all"," finds every match; ",[15,10001,10002],{},"preg_replace"," substitutes; and ",[15,10005,10006],{},"preg_replace_callback"," computes each replacement with a function.",[83,10009,10011],{"className":85,"code":10010,"language":87,"meta":88,"style":88},"preg_match('/(\\d{4})-(\\d{2})/', '2026-08', $m);   // returns 1; $m[1]='2026', $m[2]='08'\npreg_match_all('/\\d+/', 'a1b22c333', $all);       // $all[0] = ['1', '22', '333']\npreg_replace('/\\s+/', ' ', \"too   many\\tspaces\"); // 'too many spaces'\npreg_split('/[\\s,]+/', 'a, b  c');                // ['a', 'b', 'c']\npreg_replace_callback('/\\d/', fn($m) => $m[0] * 2, 'a1b2'); // 'a2b4'\n",[15,10012,10013,10051,10076,10111,10137],{"__ignoreMap":88},[92,10014,10015,10017,10019,10022,10025,10029,10032,10034,10037,10040,10042,10045,10048],{"class":94,"line":95},[92,10016,9988],{"class":102},[92,10018,120],{"class":119},[92,10020,10021],{"class":171},"'/",[92,10023,120],{"class":10024},"sns5M",[92,10026,10028],{"class":10027},"sRjNt","\\d",[92,10030,10031],{"class":10024},"{4})-(",[92,10033,10028],{"class":10027},[92,10035,10036],{"class":10024},"{2})",[92,10038,10039],{"class":171},"/'",[92,10041,195],{"class":119},[92,10043,10044],{"class":171},"'2026-08'",[92,10046,10047],{"class":119},", $m);   ",[92,10049,10050],{"class":134},"// returns 1; $m[1]='2026', $m[2]='08'\n",[92,10052,10053,10055,10057,10059,10061,10063,10065,10067,10070,10073],{"class":94,"line":106},[92,10054,9998],{"class":102},[92,10056,120],{"class":119},[92,10058,10021],{"class":171},[92,10060,10028],{"class":10027},[92,10062,1795],{"class":98},[92,10064,10039],{"class":171},[92,10066,195],{"class":119},[92,10068,10069],{"class":171},"'a1b22c333'",[92,10071,10072],{"class":119},", $all);       ",[92,10074,10075],{"class":134},"// $all[0] = ['1', '22', '333']\n",[92,10077,10078,10080,10082,10084,10087,10089,10091,10093,10096,10098,10101,10103,10106,10108],{"class":94,"line":113},[92,10079,10002],{"class":102},[92,10081,120],{"class":119},[92,10083,10021],{"class":171},[92,10085,10086],{"class":10027},"\\s",[92,10088,1795],{"class":98},[92,10090,10039],{"class":171},[92,10092,195],{"class":119},[92,10094,10095],{"class":171},"' '",[92,10097,195],{"class":119},[92,10099,10100],{"class":171},"\"too   many",[92,10102,1988],{"class":102},[92,10104,10105],{"class":171},"spaces\"",[92,10107,653],{"class":119},[92,10109,10110],{"class":134},"// 'too many spaces'\n",[92,10112,10113,10116,10118,10120,10123,10125,10127,10129,10132,10135],{"class":94,"line":138},[92,10114,10115],{"class":102},"preg_split",[92,10117,120],{"class":119},[92,10119,10021],{"class":171},[92,10121,10122],{"class":10024},"[\\s,]",[92,10124,1795],{"class":98},[92,10126,10039],{"class":171},[92,10128,195],{"class":119},[92,10130,10131],{"class":171},"'a, b  c'",[92,10133,10134],{"class":119},");                ",[92,10136,2694],{"class":134},[92,10138,10139,10141,10143,10145,10147,10149,10151,10153,10156,10158,10160,10162,10164,10166,10169,10171],{"class":94,"line":143},[92,10140,10006],{"class":102},[92,10142,120],{"class":119},[92,10144,10021],{"class":171},[92,10146,10028],{"class":10027},[92,10148,10039],{"class":171},[92,10150,195],{"class":119},[92,10152,3466],{"class":98},[92,10154,10155],{"class":119},"($m) => $m[",[92,10157,554],{"class":102},[92,10159,1751],{"class":119},[92,10161,1959],{"class":98},[92,10163,1225],{"class":102},[92,10165,195],{"class":119},[92,10167,10168],{"class":171},"'a1b2'",[92,10170,653],{"class":119},[92,10172,10173],{"class":134},"// 'a2b4'\n",[242,10175,10177],{"id":10176},"spl-data-structures","SPL data structures",[11,10179,10180,10181,834,10184,10186,10187,653,10189,10192,10193,529,10196,10199,10200,10203],{},"When a plain array is the wrong shape, the Standard PHP Library (SPL) provides real data structures as classes. ",[15,10182,10183],{},"SplStack",[15,10185,4574],{}," give O(1) pushes and pops from the right ends (unlike ",[15,10188,3214],{},[15,10190,10191],{},"SplPriorityQueue"," and the ",[15,10194,10195],{},"SplMinHeap",[15,10197,10198],{},"SplMaxHeap"," classes give you a heap for Dijkstra-style and top-k problems; and ",[15,10201,10202],{},"SplObjectStorage"," acts as a set or map keyed by object identity.",[83,10205,10207],{"className":85,"code":10206,"language":87,"meta":88,"style":88},"$stack = new SplStack();\n$stack->push(1); $stack->push(2);\n$stack->top();      // 2 (peek)\n$stack->pop();      // 2\n\n$queue = new SplQueue();\n$queue->enqueue('a'); $queue->enqueue('b');\n$queue->dequeue();  // 'a'  (O(1), unlike array_shift)\n\n$heap = new SplMinHeap();\n$heap->insert(5); $heap->insert(1); $heap->insert(3);\n$heap->extract();   // 1  (always the smallest first)\n\n$pq = new SplPriorityQueue();\n$pq->insert('low task', 1);\n$pq->insert('urgent', 10);\n$pq->extract();     // 'urgent'  (highest priority first)\n",[15,10208,10209,10223,10250,10264,10277,10281,10295,10322,10337,10341,10355,10392,10406,10410,10424,10444,10463],{"__ignoreMap":88},[92,10210,10211,10214,10216,10218,10221],{"class":94,"line":95},[92,10212,10213],{"class":119},"$stack ",[92,10215,126],{"class":98},[92,10217,6274],{"class":98},[92,10219,10220],{"class":102}," SplStack",[92,10222,7730],{"class":119},[92,10224,10225,10228,10230,10233,10235,10237,10240,10242,10244,10246,10248],{"class":94,"line":106},[92,10226,10227],{"class":119},"$stack",[92,10229,1996],{"class":98},[92,10231,10232],{"class":5161},"push",[92,10234,120],{"class":119},[92,10236,68],{"class":102},[92,10238,10239],{"class":119},"); $stack",[92,10241,1996],{"class":98},[92,10243,10232],{"class":5161},[92,10245,120],{"class":119},[92,10247,354],{"class":102},[92,10249,6289],{"class":119},[92,10251,10252,10254,10256,10259,10261],{"class":94,"line":113},[92,10253,10227],{"class":119},[92,10255,1996],{"class":98},[92,10257,10258],{"class":5161},"top",[92,10260,6302],{"class":119},[92,10262,10263],{"class":134},"// 2 (peek)\n",[92,10265,10266,10268,10270,10273,10275],{"class":94,"line":138},[92,10267,10227],{"class":119},[92,10269,1996],{"class":98},[92,10271,10272],{"class":5161},"pop",[92,10274,6302],{"class":119},[92,10276,2582],{"class":134},[92,10278,10279],{"class":94,"line":143},[92,10280,110],{"emptyLinePlaceholder":109},[92,10282,10283,10286,10288,10290,10293],{"class":94,"line":149},[92,10284,10285],{"class":119},"$queue ",[92,10287,126],{"class":98},[92,10289,6274],{"class":98},[92,10291,10292],{"class":102}," SplQueue",[92,10294,7730],{"class":119},[92,10296,10297,10300,10302,10305,10307,10309,10312,10314,10316,10318,10320],{"class":94,"line":155},[92,10298,10299],{"class":119},"$queue",[92,10301,1996],{"class":98},[92,10303,10304],{"class":5161},"enqueue",[92,10306,120],{"class":119},[92,10308,1844],{"class":171},[92,10310,10311],{"class":119},"); $queue",[92,10313,1996],{"class":98},[92,10315,10304],{"class":5161},[92,10317,120],{"class":119},[92,10319,198],{"class":171},[92,10321,6289],{"class":119},[92,10323,10324,10326,10328,10331,10334],{"class":94,"line":161},[92,10325,10299],{"class":119},[92,10327,1996],{"class":98},[92,10329,10330],{"class":5161},"dequeue",[92,10332,10333],{"class":119},"();  ",[92,10335,10336],{"class":134},"// 'a'  (O(1), unlike array_shift)\n",[92,10338,10339],{"class":94,"line":166},[92,10340,110],{"emptyLinePlaceholder":109},[92,10342,10343,10346,10348,10350,10353],{"class":94,"line":187},[92,10344,10345],{"class":119},"$heap ",[92,10347,126],{"class":98},[92,10349,6274],{"class":98},[92,10351,10352],{"class":102}," SplMinHeap",[92,10354,7730],{"class":119},[92,10356,10357,10360,10362,10365,10367,10369,10372,10374,10376,10378,10380,10382,10384,10386,10388,10390],{"class":94,"line":217},[92,10358,10359],{"class":119},"$heap",[92,10361,1996],{"class":98},[92,10363,10364],{"class":5161},"insert",[92,10366,120],{"class":119},[92,10368,1463],{"class":102},[92,10370,10371],{"class":119},"); $heap",[92,10373,1996],{"class":98},[92,10375,10364],{"class":5161},[92,10377,120],{"class":119},[92,10379,68],{"class":102},[92,10381,10371],{"class":119},[92,10383,1996],{"class":98},[92,10385,10364],{"class":5161},[92,10387,120],{"class":119},[92,10389,1448],{"class":102},[92,10391,6289],{"class":119},[92,10393,10394,10396,10398,10401,10403],{"class":94,"line":712},[92,10395,10359],{"class":119},[92,10397,1996],{"class":98},[92,10399,10400],{"class":5161},"extract",[92,10402,7178],{"class":119},[92,10404,10405],{"class":134},"// 1  (always the smallest first)\n",[92,10407,10408],{"class":94,"line":730},[92,10409,110],{"emptyLinePlaceholder":109},[92,10411,10412,10415,10417,10419,10422],{"class":94,"line":747},[92,10413,10414],{"class":119},"$pq ",[92,10416,126],{"class":98},[92,10418,6274],{"class":98},[92,10420,10421],{"class":102}," SplPriorityQueue",[92,10423,7730],{"class":119},[92,10425,10426,10429,10431,10433,10435,10438,10440,10442],{"class":94,"line":763},[92,10427,10428],{"class":119},"$pq",[92,10430,1996],{"class":98},[92,10432,10364],{"class":5161},[92,10434,120],{"class":119},[92,10436,10437],{"class":171},"'low task'",[92,10439,195],{"class":119},[92,10441,68],{"class":102},[92,10443,6289],{"class":119},[92,10445,10446,10448,10450,10452,10454,10457,10459,10461],{"class":94,"line":780},[92,10447,10428],{"class":119},[92,10449,1996],{"class":98},[92,10451,10364],{"class":5161},[92,10453,120],{"class":119},[92,10455,10456],{"class":171},"'urgent'",[92,10458,195],{"class":119},[92,10460,4419],{"class":102},[92,10462,6289],{"class":119},[92,10464,10465,10467,10469,10471,10474],{"class":94,"line":785},[92,10466,10428],{"class":119},[92,10468,1996],{"class":98},[92,10470,10400],{"class":5161},[92,10472,10473],{"class":119},"();     ",[92,10475,10476],{"class":134},"// 'urgent'  (highest priority first)\n",[11,10478,10479],{},"For interview problems, associative arrays cover the great majority of your hash-map and set needs, the debugging functions let you inspect state fast, and the SPL classes are the escape hatch when you need a genuine heap or an O(1) queue that array functions cannot provide.",[39,10481,10483],{"id":10482},"gotchas-that-actually-bite","Gotchas That Actually Bite",[11,10485,10486],{},"These are the PHP-specific traps that turn a working solution into a wrong one, especially when your instincts come from another language. Each fix is usually a one-token change once you know the rule.",[11,10488,10489,10493,10494,10496,10497,987,10499,10501,10502,10505,10506,10508,10509,10511,10512,10514,10515,10517],{},[10490,10491,10492],"strong",{},"Loose comparison juggles types, and PHP 8 changed the rules."," The ",[15,10495,1344],{}," operator converts operands to a common type before comparing, which is why ",[15,10498,1348],{},[15,10500,474],{},". In PHP 8, comparing a number to a non-numeric string finally does the sane thing, so ",[15,10503,10504],{},"0 == \"foo\""," is now ",[15,10507,2300],{}," (it was ",[15,10510,474],{}," in PHP 7, a long-standing source of security bugs). Default to ",[15,10513,1352],{},", which checks type and value with no conversion, and only use ",[15,10516,1344],{}," when you deliberately want numeric-string equality.",[11,10519,10520,10523,10524,195,10526,195,10528,195,10531,10534,10535,195,10538,10540,10541,10544,10545,834,10548,10551,10552,10554,10555,10558,10559,6339,10561,10563,10564,10566,10567,6339,10569,10571,10572,10574],{},[10490,10521,10522],{},"The set of falsy values is wider than you expect."," The values ",[15,10525,2300],{},[15,10527,554],{},[15,10529,10530],{},"0.0",[15,10532,10533],{},"\"\"",", the string ",[15,10536,10537],{},"\"0\"",[15,10539,390],{},", and the empty array ",[15,10542,10543],{},"[]"," are all falsy, while the strings ",[15,10546,10547],{},"\"0.0\"",[15,10549,10550],{},"\"false\""," are truthy. The ",[15,10553,10537],{},"-is-falsy rule catches form and input handling constantly, so when you mean \"is this an empty string,\" test ",[15,10556,10557],{},"=== ''",", and when a key might legitimately hold ",[15,10560,390],{},[15,10562,554],{},", use ",[15,10565,996],{}," instead of ",[15,10568,971],{},[15,10570,978],{},", both of which treat a ",[15,10573,390],{}," value as absent.",[11,10576,10577,10582,10583,10585,10586,10589,10590,10592,10593,10595,10596,10598,10599,10601],{},[10490,10578,10579,10581],{},[15,10580,2449],{}," and friends return a falsy index."," Because a match at the start of a string returns integer ",[15,10584,554],{},", writing ",[15,10587,10588],{},"if (strpos($haystack, $needle))"," misfires whenever the needle sits at position ",[15,10591,554],{},". Compare against ",[15,10594,2300],{}," explicitly with ",[15,10597,2889],{},", or sidestep the whole issue with ",[15,10600,2893],{}," when you only need a boolean.",[11,10603,10604,10607,10608,10610],{},[10490,10605,10606],{},"Arrays are value types, but objects are handles."," Assigning or passing an array copies it (via copy-on-write), so changing the copy leaves the original untouched, which is the opposite of what Java, Python, and JavaScript developers expect from a \"collection.\" Objects, by contrast, are assigned and passed by handle, so two variables point at one object and a mutation through either is visible through the other. Use ",[15,10609,8482],{}," when you need an independent object.",[11,10612,10613],{},[3108,10614],{"alt":10615,"src":10616},"Array assignment creates an independent copy while object assignment shares one object","/post-images/php-syntax-recap/php-value-vs-reference.png",[11,10618,10619,10624,10625,10628,10629,10632,10633,10636,10637,10640],{},[10490,10620,6686,10621,10623],{},[15,10622,4394],{}," reference outlives the loop."," After ",[15,10626,10627],{},"foreach ($arr as &$v) { ... }",", the variable ",[15,10630,10631],{},"$v"," is still a reference bound to the last element, so a later ",[15,10634,10635],{},"foreach ($arr as $v)"," overwrites that last element instead of a fresh variable and silently corrupts the array. Always ",[15,10638,10639],{},"unset($v)"," immediately after any loop that takes its value by reference.",[11,10642,10643,10648,10649,10652,10653,10656,10657,10660,10661,10664,10665,10667],{},[10490,10644,10645,10647],{},[15,10646,3326],{}," keeps the original keys."," Filtering ",[15,10650,10651],{},"[10, 20, 30]"," down to the elements greater than 15 yields ",[15,10654,10655],{},"[1 => 20, 2 => 30]",", not a freshly indexed list, so ",[15,10658,10659],{},"$result[0]"," is undefined and a ",[15,10662,10663],{},"for ($i = 0; ...)"," loop breaks. Wrap the result in ",[15,10666,3341],{}," whenever you need a clean, zero-based list afterward.",[11,10669,10670,1644,10677,10680,10681,547,10684,10687,10688,10691,10692,10694,10695,10697,10698,10700,10701,10703],{},[10490,10671,10672,10192,10674,10676],{},[15,10673,3584],{},[15,10675,1795],{}," operator disagree on keys.",[15,10678,10679],{},"array_merge([1, 2], [3, 4])"," renumbers the integer keys and gives ",[15,10682,10683],{},"[1, 2, 3, 4]",[15,10685,10686],{},"[1, 2] + [3, 4]"," is a union that keeps the left side's keys and gives ",[15,10689,10690],{},"[1, 2]",". For string keys it reverses: ",[15,10693,3584],{}," lets the later value win, while ",[15,10696,1795],{}," keeps the earlier one. Pick ",[15,10699,3584],{}," to concatenate lists and ",[15,10702,1795],{}," to supply defaults for missing keys.",[11,10705,10706,10709,10710,195,10712,10714,10715,10718,10719,1524,10722,10724,10725,10728],{},[10490,10707,10708],{},"Sorting functions return a boolean and sort in place."," Because ",[15,10711,4099],{},[15,10713,4153],{},", and their relatives mutate the array, ",[15,10716,10717],{},"$sorted = sort($arr)"," sets ",[15,10720,10721],{},"$sorted",[15,10723,474],{}," and leaves the sorted data in ",[15,10726,10727],{},"$arr",". Sort the array, then keep using that same array; never assign the return value expecting the sorted result.",[11,10730,10731,10734,10735,834,10738,10741,10742,10745,10746,195,10748,10750,10751,394,10753,10755,10756,10758],{},[10490,10732,10733],{},"Integer-like string keys become integers."," PHP normalizes array keys, so ",[15,10736,10737],{},"$a[\"1\"]",[15,10739,10740],{},"$a[1]"," are the same slot, a float key like ",[15,10743,10744],{},"$a[1.9]"," truncates to ",[15,10747,68],{},[15,10749,474],{}," becomes ",[15,10752,68],{},[15,10754,390],{}," becomes the empty string ",[15,10757,10533],{},". This matters when keys arrive from mixed sources such as JSON or form data and you assume a string key stayed a string.",[11,10760,10761,1644,10764,10767,10768,6339,10771,10774],{},[10490,10762,10763],{},"Integer overflow silently becomes a float.",[15,10765,10766],{},"PHP_INT_MAX + 1"," does not wrap around like a fixed-width integer; it promotes to a float and loses exact integer precision beyond a point. For large-integer arithmetic (factorials, big accumulations), use the ",[15,10769,10770],{},"BCMath",[15,10772,10773],{},"GMP"," extensions rather than trusting native ints.",[11,10776,10777,10780,10781,987,10784,10786,10787,6339,10789,10791,10792,10795],{},[10490,10778,10779],{},"Floating-point equality is unreliable."," Because floats are binary approximations, ",[15,10782,10783],{},"0.1 + 0.2 === 0.3",[15,10785,2300],{},". Never compare floats with ",[15,10788,1344],{},[15,10790,1352],{},"; instead check that the absolute difference is below a small tolerance, for example ",[15,10793,10794],{},"abs($a - $b) \u003C PHP_FLOAT_EPSILON",", or work in integer cents for money.",[11,10797,10798,10805,10806,834,10808,10810,10811,10814,10815,1517,10817,10820,10821,1524,10824,10827,10828,10830,10831,834,10833,10835,10836,529,10838,10840],{},[10490,10799,10800,834,10802,10804],{},[15,10801,1495],{},[15,10803,1505],{}," have different precedence."," The word forms ",[15,10807,1505],{},[15,10809,1508],{}," bind ",[1511,10812,10813],{},"looser"," than ",[15,10816,126],{},[15,10818,10819],{},"$result = doThing() or fallback()"," assigns only the result of ",[15,10822,10823],{},"doThing()",[15,10825,10826],{},"$result"," before the ",[15,10829,1508],{}," runs. Use ",[15,10832,1495],{},[15,10834,1498],{}," in expressions, and reserve ",[15,10837,1505],{},[15,10839,1508],{}," for the rare control-flow idiom where you actually want that low precedence.",[11,10842,10843,1644,10846,195,10849,394,10852,10855,10856,10858,10859,10861,10862,9072,10864,10866,10867,6339,10870,81],{},[10490,10844,10845],{},"Division and modulo by zero throw in PHP 8.",[15,10847,10848],{},"intdiv(1, 0)",[15,10850,10851],{},"1 % 0",[15,10853,10854],{},"1 / 0"," all throw ",[15,10857,9045],{}," now (PHP 7 returned ",[15,10860,2300],{}," with a warning), and that error is an ",[15,10863,9038],{},[15,10865,9034],{},". Guard the divisor, or wrap the operation in ",[15,10868,10869],{},"catch (DivisionByZeroError $e)",[15,10871,10872],{},"catch (Throwable $e)",[11,10874,10875,10878,10879,10882,10883,10885],{},[10490,10876,10877],{},"Nested ternaries must be parenthesized."," PHP 8 made an unparenthesized nested ternary a fatal error, because the old left-associative grouping surprised almost everyone. Always write ",[15,10880,10881],{},"$a ? $b : ($c ? $d : $e)"," with explicit parentheses, or restructure it as a ",[15,10884,17],{}," expression, which reads far better for multi-way choices.",[10887,10888,10889],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s4JwU, html code.shiki .s4JwU{--shiki-default:#85E89D}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sns5M, html code.shiki .sns5M{--shiki-default:#DBEDFF}html pre.shiki code .sRjNt, html code.shiki .sRjNt{--shiki-default:#85E89D;--shiki-default-font-weight:bold}",{"title":88,"searchDepth":106,"depth":106,"links":10891},[10892,10893,10900,10907,10913,10921,10925,10933,10949,10955,10963],{"id":41,"depth":106,"text":42},{"id":239,"depth":106,"text":240,"children":10894},[10895,10896,10897,10898,10899],{"id":244,"depth":113,"text":245},{"id":363,"depth":113,"text":364},{"id":514,"depth":113,"text":515},{"id":806,"depth":113,"text":807},{"id":964,"depth":113,"text":965},{"id":1154,"depth":106,"text":1155,"children":10901},[10902,10903,10904,10905,10906],{"id":1158,"depth":113,"text":1159},{"id":1337,"depth":113,"text":1338},{"id":1488,"depth":113,"text":1489},{"id":1628,"depth":113,"text":1629},{"id":1788,"depth":113,"text":1789},{"id":1975,"depth":106,"text":1976,"children":10908},[10909,10910,10911,10912],{"id":1979,"depth":113,"text":1980},{"id":2208,"depth":113,"text":2209},{"id":2285,"depth":113,"text":2286},{"id":2792,"depth":113,"text":2793},{"id":2897,"depth":106,"text":2898,"children":10914},[10915,10916,10917,10918,10919,10920],{"id":2901,"depth":113,"text":2902},{"id":3114,"depth":113,"text":3115},{"id":3315,"depth":113,"text":3316},{"id":3577,"depth":113,"text":3578},{"id":4051,"depth":113,"text":4052},{"id":4383,"depth":113,"text":4384},{"id":4578,"depth":106,"text":4579,"children":10922},[10923,10924],{"id":4582,"depth":113,"text":4583},{"id":4878,"depth":113,"text":4879},{"id":5124,"depth":106,"text":5125,"children":10926},[10927,10928,10929,10930,10931,10932],{"id":5128,"depth":113,"text":5129},{"id":5328,"depth":113,"text":5329},{"id":5486,"depth":113,"text":5487},{"id":5601,"depth":113,"text":5602},{"id":5828,"depth":113,"text":5829},{"id":5921,"depth":113,"text":5922},{"id":6092,"depth":106,"text":6093,"children":10934},[10935,10937,10938,10939,10940,10941,10942,10943,10944,10945,10946,10947,10948],{"id":6096,"depth":113,"text":10936},"Classes, objects, and $this",{"id":6320,"depth":113,"text":6321},{"id":6465,"depth":113,"text":6466},{"id":6682,"depth":113,"text":6683},{"id":6809,"depth":113,"text":6810},{"id":6993,"depth":113,"text":6994},{"id":7184,"depth":113,"text":7185},{"id":7412,"depth":113,"text":7413},{"id":7653,"depth":113,"text":7654},{"id":7902,"depth":113,"text":7903},{"id":8184,"depth":113,"text":8185},{"id":8465,"depth":113,"text":8466},{"id":8615,"depth":113,"text":8616},{"id":8750,"depth":106,"text":8751,"children":10950},[10951,10952,10953,10954],{"id":8754,"depth":113,"text":8755},{"id":8928,"depth":113,"text":8929},{"id":9023,"depth":113,"text":9024},{"id":9087,"depth":113,"text":9088},{"id":9291,"depth":106,"text":9292,"children":10956},[10957,10958,10959,10960,10961,10962],{"id":9295,"depth":113,"text":9296},{"id":9419,"depth":113,"text":9420},{"id":9672,"depth":113,"text":9673},{"id":9817,"depth":113,"text":9818},{"id":9974,"depth":113,"text":9975},{"id":10176,"depth":113,"text":10177},{"id":10482,"depth":106,"text":10483},"2026-08-30","A PHP 8 syntax recap for developers prepping for a coding interview or ramping onto a PHP codebase: variables, types, operators, strings, arrays, control flow, functions, OOP, exceptions, and the standard-library functions and gotchas you actually use, with runnable examples for every concept.",false,"md",null,"php-syntax-recap.png",{},"/backend/php-syntax-recap",{"title":5,"description":10965},"Backend/8.php-syntax-recap",[10975,10976,10977,10978,10979],"PHP","Interview","Backend","Syntax","Web Development","m0XwaB1sbh_d4izt-Oew40xDUhIE-aFcO76sAtEzy64",[10982,15402,24211,31342,42071],{"id":10983,"title":10984,"author":6,"body":10985,"date":15390,"description":15391,"draft":10966,"extension":10967,"guide":10968,"image":15392,"meta":15393,"navigation":109,"path":15394,"seo":15395,"stem":15396,"tags":15397,"__hash__":15401},"blog/Backend/10.deploy-laravel-on-aws-lambda-with-bref.md","How to Deploy a Laravel Application on AWS Lambda With Bref: Step-by-Step Tutorial",{"type":8,"value":10986,"toc":15359},[10987,10994,11008,11012,11015,11040,11044,11047,11058,11062,11073,11098,11101,11107,11111,11114,11118,11121,11127,11131,11134,11176,11180,11183,11186,11305,11308,11412,11415,11449,11452,11755,11758,11762,11765,11787,11790,11812,11828,11832,11838,12316,12319,12341,12363,12371,12407,12415,12443,12451,12472,12478,12482,12485,12489,12495,12522,12535,12690,12694,12718,12728,12842,12854,12862,12866,12872,12896,12909,13002,13006,13023,13027,13036,13167,13171,13182,13896,13900,13924,13932,13988,13994,14010,14115,14122,14136,14154,14158,14164,14184,14329,14334,14368,14386,14390,14408,14415,14487,14499,14503,14514,14517,14534,14548,14559,14570,14581,14585,14595,14606,14624,14641,14742,14760,14768,14772,14787,14830,14857,14861,14864,15115,15122,15125,15168,15190,15205,15209,15269,15272,15276,15282,15288,15294,15300,15306,15315,15319,15322,15326,15346,15356],[11,10988,10989,10990,10993],{},"Running PHP on AWS Lambda gives you no servers to patch and a bill that scales to zero. It also gives you a read-only disk, no queue daemon, and a 29-second request limit. This guide shows how to deploy Laravel serverless on AWS Lambda with ",[10490,10991,10992],{},"Bref",", the open-source tool that runs PHP on Lambda. It is a complete Laravel serverless deployment: you take a fresh app to production, wiring up the web, queue, scheduler, uploads, a custom domain, and CI, and hitting the real problems, not just the happy path.",[11,10995,10996,10997,11000,11001,11004,11005,81],{},"Names used throughout: app ",[15,10998,10999],{},"acme-app",", domain ",[15,11002,11003],{},"example.com",", region ",[15,11006,11007],{},"ap-south-1",[39,11009,11011],{"id":11010},"what-you-will-build","What you will build",[11,11013,11014],{},"A small Laravel app with placeholder code that exercises every moving part:",[11016,11017,11018,11022,11025,11028,11031,11034,11037],"ul",{},[11019,11020,11021],"li",{},"a web endpoint behind API Gateway,",[11019,11023,11024],{},"a queued job draining from SQS,",[11019,11026,11027],{},"a scheduled command running every minute,",[11019,11029,11030],{},"a custom artisan command you run on demand,",[11019,11032,11033],{},"a file upload that stores to S3,",[11019,11035,11036],{},"session and cache backed by DynamoDB,",[11019,11038,11039],{},"a health-check route.",[39,11041,11043],{"id":11042},"before-you-start","Before you start",[11,11045,11046],{},"You need:",[11016,11048,11049,11052,11055],{},[11019,11050,11051],{},"an AWS account,",[11019,11053,11054],{},"a domain with DNS on Cloudflare (or another external DNS provider),",[11019,11056,11057],{},"local tools: PHP 8.3, Composer, Docker (for Sail), Node.js and the AWS CLI.",[39,11059,11061],{"id":11060},"how-serverless-changes-a-laravel-app","How serverless changes a Laravel app",[11,11063,11064,11065,11068,11069,11072],{},"Bref packages PHP as Lambda layers (a ",[1511,11066,11067],{},"layer"," is a zip of shared files Lambda mounts into your function) so a normal Laravel app boots on ",[10490,11070,11071],{},"AWS Lambda"," (code that runs on demand, per request, with no server). Three rules follow, and they drive the whole guide:",[11074,11075,11076,11082,11092],"ol",{},[11019,11077,11078,11081],{},[10490,11079,11080],{},"No server."," The app wakes per request and freezes after. Nothing survives in memory between requests.",[11019,11083,11084,11087,11088,11091],{},[10490,11085,11086],{},"Read-only disk."," Only ",[15,11089,11090],{},"/tmp"," is writable, and only per instance. File sessions, the file cache, and file logs all break.",[11019,11093,11094,11097],{},[10490,11095,11096],{},"No long processes."," A web request must finish in 29 seconds. Long work moves to a queue.",[11,11099,11100],{},"The fix for all three is the same: move Laravel's file, session, cache, and queue drivers to managed AWS services. That is what makes a serverless Laravel app work, and it is most of the work below.",[11,11102,11103,11106],{},[10490,11104,11105],{},"When does serverless Laravel fit?"," It suits spiky or low traffic, where Lambda scales to zero and you pay per request. It fits less well for steady high traffic or long-lived processes (WebSockets, Laravel Octane, Horizon), where an always-on server is simpler and cheaper.",[242,11108,11110],{"id":11109},"bref-or-laravel-vapor","Bref or Laravel Vapor?",[11,11112,11113],{},"Both run Laravel on AWS Lambda. Laravel Vapor is a paid, managed service with a dashboard. Bref is open-source and free, and you own the AWS config directly. Pick Vapor for convenience, Bref for control and no per-project fee. This guide uses Bref.",[39,11115,11117],{"id":11116},"architecture","Architecture",[11,11119,11120],{},"Keep this picture open while you follow the steps. Three Lambda functions (web, worker, console) sit behind managed services that hold the state Lambda cannot.",[11,11122,11123],{},[3108,11124],{"alt":11125,"src":11126},"Architecture diagram of a Laravel application on AWS Lambda with Bref, showing Cloudflare DNS, CloudFront, API Gateway routing to the web Lambda, SQS feeding the worker Lambda, EventBridge triggering the console Lambda, with DynamoDB, S3, and CloudWatch as managed services","/post-images/deploy-laravel-on-aws-lambda-with-bref/laravel-aws-lambda-bref-architecture-diagram.png",[39,11128,11130],{"id":11129},"step-1-create-the-laravel-app","Step 1: Create the Laravel app",[11,11132,11133],{},"Use Sail (Laravel's Docker environment) so you do not install PHP or MySQL locally.",[83,11135,11139],{"className":11136,"code":11137,"language":11138,"meta":88,"style":88},"language-bash shiki shiki-themes github-dark","curl -s \"https://laravel.build/acme-app?with=mysql,redis\" | bash\ncd acme-app\n./vendor/bin/sail up -d\n","bash",[15,11140,11141,11157,11165],{"__ignoreMap":88},[92,11142,11143,11146,11149,11152,11154],{"class":94,"line":95},[92,11144,11145],{"class":5161},"curl",[92,11147,11148],{"class":102}," -s",[92,11150,11151],{"class":171}," \"https://laravel.build/acme-app?with=mysql,redis\"",[92,11153,1909],{"class":98},[92,11155,11156],{"class":5161}," bash\n",[92,11158,11159,11162],{"class":94,"line":106},[92,11160,11161],{"class":102},"cd",[92,11163,11164],{"class":171}," acme-app\n",[92,11166,11167,11170,11173],{"class":94,"line":113},[92,11168,11169],{"class":5161},"./vendor/bin/sail",[92,11171,11172],{"class":171}," up",[92,11174,11175],{"class":102}," -d\n",[39,11177,11179],{"id":11178},"step-2-add-the-demo-pieces","Step 2: Add the demo pieces",[11,11181,11182],{},"Each piece is intentionally dumb. The goal is to test the plumbing. The file path is the first line of every block.",[11,11184,11185],{},"Add a queued job that only logs:",[83,11187,11189],{"className":85,"code":11188,"language":87,"meta":88,"style":88},"// app/Jobs/ProcessUpload.php\nclass ProcessUpload implements ShouldQueue\n{\n    use Queueable;\n\n    public function __construct(public string $path) {}\n\n    public function handle(): void\n    {\n        Log::info('Processing upload', ['path' => $this->path]);\n    }\n}\n",[15,11190,11191,11196,11208,11213,11222,11226,11243,11247,11263,11268,11297,11301],{"__ignoreMap":88},[92,11192,11193],{"class":94,"line":95},[92,11194,11195],{"class":134},"// app/Jobs/ProcessUpload.php\n",[92,11197,11198,11200,11203,11205],{"class":94,"line":106},[92,11199,6122],{"class":98},[92,11201,11202],{"class":5161}," ProcessUpload",[92,11204,7522],{"class":98},[92,11206,11207],{"class":5161}," ShouldQueue\n",[92,11209,11210],{"class":94,"line":113},[92,11211,11212],{"class":119},"{\n",[92,11214,11215,11217,11220],{"class":94,"line":138},[92,11216,7819],{"class":98},[92,11218,11219],{"class":102}," Queueable",[92,11221,229],{"class":119},[92,11223,11224],{"class":94,"line":143},[92,11225,110],{"emptyLinePlaceholder":109},[92,11227,11228,11230,11232,11234,11236,11238,11240],{"class":94,"line":149},[92,11229,6132],{"class":98},[92,11231,5659],{"class":98},[92,11233,6163],{"class":102},[92,11235,120],{"class":119},[92,11237,6327],{"class":98},[92,11239,5188],{"class":98},[92,11241,11242],{"class":119}," $path) {}\n",[92,11244,11245],{"class":94,"line":155},[92,11246,110],{"emptyLinePlaceholder":109},[92,11248,11249,11251,11253,11256,11258,11260],{"class":94,"line":161},[92,11250,6132],{"class":98},[92,11252,5659],{"class":98},[92,11254,11255],{"class":5161}," handle",[92,11257,6042],{"class":119},[92,11259,5185],{"class":98},[92,11261,11262],{"class":98}," void\n",[92,11264,11265],{"class":94,"line":166},[92,11266,11267],{"class":119},"    {\n",[92,11269,11270,11273,11275,11278,11280,11283,11285,11288,11290,11292,11294],{"class":94,"line":187},[92,11271,11272],{"class":102},"        Log",[92,11274,6818],{"class":98},[92,11276,11277],{"class":5161},"info",[92,11279,120],{"class":119},[92,11281,11282],{"class":171},"'Processing upload'",[92,11284,2708],{"class":119},[92,11286,11287],{"class":171},"'path'",[92,11289,1019],{"class":98},[92,11291,6239],{"class":102},[92,11293,1996],{"class":98},[92,11295,11296],{"class":119},"path]);\n",[92,11298,11299],{"class":94,"line":217},[92,11300,5104],{"class":119},[92,11302,11303],{"class":94,"line":712},[92,11304,4711],{"class":119},[11,11306,11307],{},"Add a custom artisan command:",[83,11309,11311],{"className":85,"code":11310,"language":87,"meta":88,"style":88},"// app/Console/Commands/Heartbeat.php\nclass Heartbeat extends Command\n{\n    protected $signature = 'acme:heartbeat';\n\n    public function handle(): void\n    {\n        Log::info('heartbeat', ['at' => now()->toIso8601String()]);\n    }\n}\n",[15,11312,11313,11318,11330,11334,11349,11353,11367,11371,11404,11408],{"__ignoreMap":88},[92,11314,11315],{"class":94,"line":95},[92,11316,11317],{"class":134},"// app/Console/Commands/Heartbeat.php\n",[92,11319,11320,11322,11325,11327],{"class":94,"line":106},[92,11321,6122],{"class":98},[92,11323,11324],{"class":5161}," Heartbeat",[92,11326,7096],{"class":98},[92,11328,11329],{"class":5161}," Command\n",[92,11331,11332],{"class":94,"line":113},[92,11333,11212],{"class":119},[92,11335,11336,11339,11342,11344,11347],{"class":94,"line":138},[92,11337,11338],{"class":98},"    protected",[92,11340,11341],{"class":119}," $signature ",[92,11343,126],{"class":98},[92,11345,11346],{"class":171}," 'acme:heartbeat'",[92,11348,229],{"class":119},[92,11350,11351],{"class":94,"line":143},[92,11352,110],{"emptyLinePlaceholder":109},[92,11354,11355,11357,11359,11361,11363,11365],{"class":94,"line":149},[92,11356,6132],{"class":98},[92,11358,5659],{"class":98},[92,11360,11255],{"class":5161},[92,11362,6042],{"class":119},[92,11364,5185],{"class":98},[92,11366,11262],{"class":98},[92,11368,11369],{"class":94,"line":155},[92,11370,11267],{"class":119},[92,11372,11373,11375,11377,11379,11381,11384,11386,11389,11391,11394,11396,11398,11401],{"class":94,"line":161},[92,11374,11272],{"class":102},[92,11376,6818],{"class":98},[92,11378,11277],{"class":5161},[92,11380,120],{"class":119},[92,11382,11383],{"class":171},"'heartbeat'",[92,11385,2708],{"class":119},[92,11387,11388],{"class":171},"'at'",[92,11390,1019],{"class":98},[92,11392,11393],{"class":5161}," now",[92,11395,6042],{"class":119},[92,11397,1996],{"class":98},[92,11399,11400],{"class":5161},"toIso8601String",[92,11402,11403],{"class":119},"()]);\n",[92,11405,11406],{"class":94,"line":166},[92,11407,5104],{"class":119},[92,11409,11410],{"class":94,"line":187},[92,11411,4711],{"class":119},[11,11413,11414],{},"Schedule it every minute:",[83,11416,11418],{"className":85,"code":11417,"language":87,"meta":88,"style":88},"// routes/console.php\nSchedule::command('acme:heartbeat')->everyMinute();\n",[15,11419,11420,11425],{"__ignoreMap":88},[92,11421,11422],{"class":94,"line":95},[92,11423,11424],{"class":134},"// routes/console.php\n",[92,11426,11427,11430,11432,11435,11437,11440,11442,11444,11447],{"class":94,"line":106},[92,11428,11429],{"class":102},"Schedule",[92,11431,6818],{"class":98},[92,11433,11434],{"class":5161},"command",[92,11436,120],{"class":119},[92,11438,11439],{"class":171},"'acme:heartbeat'",[92,11441,5182],{"class":119},[92,11443,1996],{"class":98},[92,11445,11446],{"class":5161},"everyMinute",[92,11448,7730],{"class":119},[11,11450,11451],{},"Add the routes: a health check, a cache-and-session counter, and an upload that stores to S3 and dispatches the job.",[83,11453,11455],{"className":85,"code":11454,"language":87,"meta":88,"style":88},"// routes/web.php\nRoute::get('/health', fn () => response()->json(['ok' => true, 'at' => now()]));\n\nRoute::get('/counter', function (Request $request) {\n    $hits = Cache::increment('hits');\n    $request->session()->put('last_seen', now()->toIso8601String());\n    return response()->json(['hits' => $hits]);\n});\n\nRoute::post('/uploads', function (Request $request) {\n    $request->validate(['file' => 'required|file|max:10240']);\n    $path = $request->file('file')->store('uploads', 's3');\n    ProcessUpload::dispatch($path);\n    return response()->json(['path' => $path], 201);\n});\n",[15,11456,11457,11462,11512,11516,11541,11563,11598,11620,11625,11629,11653,11675,11713,11726,11751],{"__ignoreMap":88},[92,11458,11459],{"class":94,"line":95},[92,11460,11461],{"class":134},"// routes/web.php\n",[92,11463,11464,11467,11469,11471,11473,11476,11478,11480,11483,11486,11488,11490,11492,11494,11497,11499,11501,11503,11505,11507,11509],{"class":94,"line":106},[92,11465,11466],{"class":102},"Route",[92,11468,6818],{"class":98},[92,11470,8985],{"class":5161},[92,11472,120],{"class":119},[92,11474,11475],{"class":171},"'/health'",[92,11477,195],{"class":119},[92,11479,3466],{"class":98},[92,11481,11482],{"class":119}," () => ",[92,11484,11485],{"class":5161},"response",[92,11487,6042],{"class":119},[92,11489,1996],{"class":98},[92,11491,9672],{"class":5161},[92,11493,486],{"class":119},[92,11495,11496],{"class":171},"'ok'",[92,11498,1019],{"class":98},[92,11500,295],{"class":102},[92,11502,195],{"class":119},[92,11504,11388],{"class":171},[92,11506,1019],{"class":98},[92,11508,11393],{"class":5161},[92,11510,11511],{"class":119},"()]));\n",[92,11513,11514],{"class":94,"line":113},[92,11515,110],{"emptyLinePlaceholder":109},[92,11517,11518,11520,11522,11524,11526,11529,11531,11533,11535,11538],{"class":94,"line":138},[92,11519,11466],{"class":102},[92,11521,6818],{"class":98},[92,11523,8985],{"class":5161},[92,11525,120],{"class":119},[92,11527,11528],{"class":171},"'/counter'",[92,11530,195],{"class":119},[92,11532,3556],{"class":98},[92,11534,3559],{"class":119},[92,11536,11537],{"class":102},"Request",[92,11539,11540],{"class":119}," $request) {\n",[92,11542,11543,11546,11548,11551,11553,11556,11558,11561],{"class":94,"line":143},[92,11544,11545],{"class":119},"    $hits ",[92,11547,126],{"class":98},[92,11549,11550],{"class":102}," Cache",[92,11552,6818],{"class":98},[92,11554,11555],{"class":5161},"increment",[92,11557,120],{"class":119},[92,11559,11560],{"class":171},"'hits'",[92,11562,6289],{"class":119},[92,11564,11565,11568,11570,11573,11575,11577,11580,11582,11585,11587,11590,11592,11594,11596],{"class":94,"line":149},[92,11566,11567],{"class":119},"    $request",[92,11569,1996],{"class":98},[92,11571,11572],{"class":5161},"session",[92,11574,6042],{"class":119},[92,11576,1996],{"class":98},[92,11578,11579],{"class":5161},"put",[92,11581,120],{"class":119},[92,11583,11584],{"class":171},"'last_seen'",[92,11586,195],{"class":119},[92,11588,11589],{"class":5161},"now",[92,11591,6042],{"class":119},[92,11593,1996],{"class":98},[92,11595,11400],{"class":5161},[92,11597,9268],{"class":119},[92,11599,11600,11602,11605,11607,11609,11611,11613,11615,11617],{"class":94,"line":155},[92,11601,5195],{"class":98},[92,11603,11604],{"class":5161}," response",[92,11606,6042],{"class":119},[92,11608,1996],{"class":98},[92,11610,9672],{"class":5161},[92,11612,486],{"class":119},[92,11614,11560],{"class":171},[92,11616,1019],{"class":98},[92,11618,11619],{"class":119}," $hits]);\n",[92,11621,11622],{"class":94,"line":161},[92,11623,11624],{"class":119},"});\n",[92,11626,11627],{"class":94,"line":166},[92,11628,110],{"emptyLinePlaceholder":109},[92,11630,11631,11633,11635,11638,11640,11643,11645,11647,11649,11651],{"class":94,"line":187},[92,11632,11466],{"class":102},[92,11634,6818],{"class":98},[92,11636,11637],{"class":5161},"post",[92,11639,120],{"class":119},[92,11641,11642],{"class":171},"'/uploads'",[92,11644,195],{"class":119},[92,11646,3556],{"class":98},[92,11648,3559],{"class":119},[92,11650,11537],{"class":102},[92,11652,11540],{"class":119},[92,11654,11655,11657,11659,11662,11664,11667,11669,11672],{"class":94,"line":217},[92,11656,11567],{"class":119},[92,11658,1996],{"class":98},[92,11660,11661],{"class":5161},"validate",[92,11663,486],{"class":119},[92,11665,11666],{"class":171},"'file'",[92,11668,1019],{"class":98},[92,11670,11671],{"class":171}," 'required|file|max:10240'",[92,11673,11674],{"class":119},"]);\n",[92,11676,11677,11680,11682,11685,11687,11690,11692,11694,11696,11698,11701,11703,11706,11708,11711],{"class":94,"line":712},[92,11678,11679],{"class":119},"    $path ",[92,11681,126],{"class":98},[92,11683,11684],{"class":119}," $request",[92,11686,1996],{"class":98},[92,11688,11689],{"class":5161},"file",[92,11691,120],{"class":119},[92,11693,11666],{"class":171},[92,11695,5182],{"class":119},[92,11697,1996],{"class":98},[92,11699,11700],{"class":5161},"store",[92,11702,120],{"class":119},[92,11704,11705],{"class":171},"'uploads'",[92,11707,195],{"class":119},[92,11709,11710],{"class":171},"'s3'",[92,11712,6289],{"class":119},[92,11714,11715,11718,11720,11723],{"class":94,"line":730},[92,11716,11717],{"class":102},"    ProcessUpload",[92,11719,6818],{"class":98},[92,11721,11722],{"class":5161},"dispatch",[92,11724,11725],{"class":119},"($path);\n",[92,11727,11728,11730,11732,11734,11736,11738,11740,11742,11744,11747,11749],{"class":94,"line":747},[92,11729,5195],{"class":98},[92,11731,11604],{"class":5161},[92,11733,6042],{"class":119},[92,11735,1996],{"class":98},[92,11737,9672],{"class":5161},[92,11739,486],{"class":119},[92,11741,11287],{"class":171},[92,11743,1019],{"class":98},[92,11745,11746],{"class":119}," $path], ",[92,11748,4743],{"class":102},[92,11750,6289],{"class":119},[92,11752,11753],{"class":94,"line":763},[92,11754,11624],{"class":119},[11,11756,11757],{},"Locally this uses files, Redis, and local disk. None of those exist on Lambda, so the next steps replace them.",[39,11759,11761],{"id":11760},"step-3-install-bref-and-the-cli","Step 3: Install Bref and the CLI",[11,11763,11764],{},"Install the PHP packages:",[83,11766,11768],{"className":11136,"code":11767,"language":11138,"meta":88,"style":88},"composer require bref/bref bref/laravel-bridge --update-with-dependencies\n",[15,11769,11770],{"__ignoreMap":88},[92,11771,11772,11775,11778,11781,11784],{"class":94,"line":95},[92,11773,11774],{"class":5161},"composer",[92,11776,11777],{"class":171}," require",[92,11779,11780],{"class":171}," bref/bref",[92,11782,11783],{"class":171}," bref/laravel-bridge",[92,11785,11786],{"class":102}," --update-with-dependencies\n",[11,11788,11789],{},"Install the deploy CLI globally (it needs Node.js):",[83,11791,11793],{"className":11136,"code":11792,"language":11138,"meta":88,"style":88},"npm i -g serverless # or: npm i -g osls\n",[15,11794,11795],{"__ignoreMap":88},[92,11796,11797,11800,11803,11806,11809],{"class":94,"line":95},[92,11798,11799],{"class":5161},"npm",[92,11801,11802],{"class":171}," i",[92,11804,11805],{"class":102}," -g",[92,11807,11808],{"class":171}," serverless",[92,11810,11811],{"class":134}," # or: npm i -g osls\n",[11813,11814,11815],"blockquote",{},[11,11816,11817,11820,11821,11824,11825,81],{},[10490,11818,11819],{},"Which CLI?"," The Serverless Framework changed its license in v4 and now charges larger organizations. ",[10490,11822,11823],{},"osls"," (\"Open Serverless\") is a free community fork of the last MIT version. Commands are identical; this guide uses ",[15,11826,11827],{},"serverless",[39,11829,11831],{"id":11830},"step-4-write-serverlessyml","Step 4: Write serverless.yml",[11,11833,11834,11837],{},[15,11835,11836],{},"serverless.yml"," is the one file that describes your whole deploy. The CLI compiles it into AWS resources. Create it in the project root with three functions, one per way your app runs.",[83,11839,11843],{"className":11840,"code":11841,"language":11842,"meta":88,"style":88},"language-yaml shiki shiki-themes github-dark","# serverless.yml\nservice: acme-app\n\nprovider:\n  name: aws\n  region: ap-south-1\n  runtime: provided.al2\n  memorySize: ${param:memory} # per-stage, from params below\n  environment:\n    APP_ENV: production\n    APP_DEBUG: 'false'\n    LOG_CHANNEL: stderr\n\n# Per-stage values. Deploy with: serverless deploy --stage prod\nparams:\n  prod:\n    memory: 1024\n    domain: example.com\n  staging:\n    memory: 512\n    domain: staging.example.com\n\nplugins:\n  - ./vendor/bref/bref\n\nfunctions:\n  web: # HTTP, behind API Gateway\n    handler: public/index.php\n    runtime: php-83-fpm\n    timeout: 28\n    environment:\n      BREF_BINARY_RESPONSES: '1'\n    events:\n      - httpApi: '*'\n\n  worker: # pulls jobs off SQS\n    handler: Bref\\LaravelBridge\\Queue\\QueueHandler\n    runtime: php-83\n    timeout: 60\n    events:\n      - sqs:\n          arn: !GetAtt JobsQueue.Arn\n          batchSize: 1\n          maximumConcurrency: 5\n\n  console: # runs artisan, including the scheduler\n    handler: artisan\n    runtime: php-83-console\n    timeout: 120\n    events:\n      - schedule:\n          rate: rate(1 minute)\n          input: '\"schedule:run\"'\n","yaml",[15,11844,11845,11850,11860,11864,11871,11881,11891,11901,11914,11921,11931,11941,11951,11955,11960,11967,11974,11984,11994,12001,12010,12019,12023,12030,12038,12042,12048,12058,12069,12080,12091,12099,12110,12118,12132,12137,12148,12158,12168,12178,12185,12195,12209,12220,12231,12236,12247,12257,12267,12277,12284,12294,12305],{"__ignoreMap":88},[92,11846,11847],{"class":94,"line":95},[92,11848,11849],{"class":134},"# serverless.yml\n",[92,11851,11852,11855,11857],{"class":94,"line":106},[92,11853,11854],{"class":2145},"service",[92,11856,5263],{"class":119},[92,11858,11859],{"class":171},"acme-app\n",[92,11861,11862],{"class":94,"line":113},[92,11863,110],{"emptyLinePlaceholder":109},[92,11865,11866,11869],{"class":94,"line":138},[92,11867,11868],{"class":2145},"provider",[92,11870,4828],{"class":119},[92,11872,11873,11876,11878],{"class":94,"line":143},[92,11874,11875],{"class":2145},"  name",[92,11877,5263],{"class":119},[92,11879,11880],{"class":171},"aws\n",[92,11882,11883,11886,11888],{"class":94,"line":149},[92,11884,11885],{"class":2145},"  region",[92,11887,5263],{"class":119},[92,11889,11890],{"class":171},"ap-south-1\n",[92,11892,11893,11896,11898],{"class":94,"line":155},[92,11894,11895],{"class":2145},"  runtime",[92,11897,5263],{"class":119},[92,11899,11900],{"class":171},"provided.al2\n",[92,11902,11903,11906,11908,11911],{"class":94,"line":161},[92,11904,11905],{"class":2145},"  memorySize",[92,11907,5263],{"class":119},[92,11909,11910],{"class":171},"${param:memory}",[92,11912,11913],{"class":134}," # per-stage, from params below\n",[92,11915,11916,11919],{"class":94,"line":166},[92,11917,11918],{"class":2145},"  environment",[92,11920,4828],{"class":119},[92,11922,11923,11926,11928],{"class":94,"line":187},[92,11924,11925],{"class":2145},"    APP_ENV",[92,11927,5263],{"class":119},[92,11929,11930],{"class":171},"production\n",[92,11932,11933,11936,11938],{"class":94,"line":217},[92,11934,11935],{"class":2145},"    APP_DEBUG",[92,11937,5263],{"class":119},[92,11939,11940],{"class":171},"'false'\n",[92,11942,11943,11946,11948],{"class":94,"line":712},[92,11944,11945],{"class":2145},"    LOG_CHANNEL",[92,11947,5263],{"class":119},[92,11949,11950],{"class":171},"stderr\n",[92,11952,11953],{"class":94,"line":730},[92,11954,110],{"emptyLinePlaceholder":109},[92,11956,11957],{"class":94,"line":747},[92,11958,11959],{"class":134},"# Per-stage values. Deploy with: serverless deploy --stage prod\n",[92,11961,11962,11965],{"class":94,"line":763},[92,11963,11964],{"class":2145},"params",[92,11966,4828],{"class":119},[92,11968,11969,11972],{"class":94,"line":780},[92,11970,11971],{"class":2145},"  prod",[92,11973,4828],{"class":119},[92,11975,11976,11979,11981],{"class":94,"line":785},[92,11977,11978],{"class":2145},"    memory",[92,11980,5263],{"class":119},[92,11982,11983],{"class":102},"1024\n",[92,11985,11986,11989,11991],{"class":94,"line":2585},[92,11987,11988],{"class":2145},"    domain",[92,11990,5263],{"class":119},[92,11992,11993],{"class":171},"example.com\n",[92,11995,11996,11999],{"class":94,"line":2605},[92,11997,11998],{"class":2145},"  staging",[92,12000,4828],{"class":119},[92,12002,12003,12005,12007],{"class":94,"line":2634},[92,12004,11978],{"class":2145},[92,12006,5263],{"class":119},[92,12008,12009],{"class":102},"512\n",[92,12011,12012,12014,12016],{"class":94,"line":2651},[92,12013,11988],{"class":2145},[92,12015,5263],{"class":119},[92,12017,12018],{"class":171},"staging.example.com\n",[92,12020,12021],{"class":94,"line":2671},[92,12022,110],{"emptyLinePlaceholder":109},[92,12024,12025,12028],{"class":94,"line":2676},[92,12026,12027],{"class":2145},"plugins",[92,12029,4828],{"class":119},[92,12031,12032,12035],{"class":94,"line":2697},[92,12033,12034],{"class":119},"  - ",[92,12036,12037],{"class":171},"./vendor/bref/bref\n",[92,12039,12040],{"class":94,"line":2726},[92,12041,110],{"emptyLinePlaceholder":109},[92,12043,12044,12046],{"class":94,"line":2755},[92,12045,5124],{"class":2145},[92,12047,4828],{"class":119},[92,12049,12050,12053,12055],{"class":94,"line":2776},[92,12051,12052],{"class":2145},"  web",[92,12054,5263],{"class":119},[92,12056,12057],{"class":134},"# HTTP, behind API Gateway\n",[92,12059,12061,12064,12066],{"class":94,"line":12060},28,[92,12062,12063],{"class":2145},"    handler",[92,12065,5263],{"class":119},[92,12067,12068],{"class":171},"public/index.php\n",[92,12070,12072,12075,12077],{"class":94,"line":12071},29,[92,12073,12074],{"class":2145},"    runtime",[92,12076,5263],{"class":119},[92,12078,12079],{"class":171},"php-83-fpm\n",[92,12081,12083,12086,12088],{"class":94,"line":12082},30,[92,12084,12085],{"class":2145},"    timeout",[92,12087,5263],{"class":119},[92,12089,12090],{"class":102},"28\n",[92,12092,12094,12097],{"class":94,"line":12093},31,[92,12095,12096],{"class":2145},"    environment",[92,12098,4828],{"class":119},[92,12100,12102,12105,12107],{"class":94,"line":12101},32,[92,12103,12104],{"class":2145},"      BREF_BINARY_RESPONSES",[92,12106,5263],{"class":119},[92,12108,12109],{"class":171},"'1'\n",[92,12111,12113,12116],{"class":94,"line":12112},33,[92,12114,12115],{"class":2145},"    events",[92,12117,4828],{"class":119},[92,12119,12121,12124,12127,12129],{"class":94,"line":12120},34,[92,12122,12123],{"class":119},"      - ",[92,12125,12126],{"class":2145},"httpApi",[92,12128,5263],{"class":119},[92,12130,12131],{"class":171},"'*'\n",[92,12133,12135],{"class":94,"line":12134},35,[92,12136,110],{"emptyLinePlaceholder":109},[92,12138,12140,12143,12145],{"class":94,"line":12139},36,[92,12141,12142],{"class":2145},"  worker",[92,12144,5263],{"class":119},[92,12146,12147],{"class":134},"# pulls jobs off SQS\n",[92,12149,12151,12153,12155],{"class":94,"line":12150},37,[92,12152,12063],{"class":2145},[92,12154,5263],{"class":119},[92,12156,12157],{"class":171},"Bref\\LaravelBridge\\Queue\\QueueHandler\n",[92,12159,12161,12163,12165],{"class":94,"line":12160},38,[92,12162,12074],{"class":2145},[92,12164,5263],{"class":119},[92,12166,12167],{"class":171},"php-83\n",[92,12169,12171,12173,12175],{"class":94,"line":12170},39,[92,12172,12085],{"class":2145},[92,12174,5263],{"class":119},[92,12176,12177],{"class":102},"60\n",[92,12179,12181,12183],{"class":94,"line":12180},40,[92,12182,12115],{"class":2145},[92,12184,4828],{"class":119},[92,12186,12188,12190,12193],{"class":94,"line":12187},41,[92,12189,12123],{"class":119},[92,12191,12192],{"class":2145},"sqs",[92,12194,4828],{"class":119},[92,12196,12198,12201,12203,12206],{"class":94,"line":12197},42,[92,12199,12200],{"class":2145},"          arn",[92,12202,5263],{"class":119},[92,12204,12205],{"class":98},"!GetAtt",[92,12207,12208],{"class":171}," JobsQueue.Arn\n",[92,12210,12212,12215,12217],{"class":94,"line":12211},43,[92,12213,12214],{"class":2145},"          batchSize",[92,12216,5263],{"class":119},[92,12218,12219],{"class":102},"1\n",[92,12221,12223,12226,12228],{"class":94,"line":12222},44,[92,12224,12225],{"class":2145},"          maximumConcurrency",[92,12227,5263],{"class":119},[92,12229,12230],{"class":102},"5\n",[92,12232,12234],{"class":94,"line":12233},45,[92,12235,110],{"emptyLinePlaceholder":109},[92,12237,12239,12242,12244],{"class":94,"line":12238},46,[92,12240,12241],{"class":2145},"  console",[92,12243,5263],{"class":119},[92,12245,12246],{"class":134},"# runs artisan, including the scheduler\n",[92,12248,12250,12252,12254],{"class":94,"line":12249},47,[92,12251,12063],{"class":2145},[92,12253,5263],{"class":119},[92,12255,12256],{"class":171},"artisan\n",[92,12258,12260,12262,12264],{"class":94,"line":12259},48,[92,12261,12074],{"class":2145},[92,12263,5263],{"class":119},[92,12265,12266],{"class":171},"php-83-console\n",[92,12268,12270,12272,12274],{"class":94,"line":12269},49,[92,12271,12085],{"class":2145},[92,12273,5263],{"class":119},[92,12275,12276],{"class":102},"120\n",[92,12278,12280,12282],{"class":94,"line":12279},50,[92,12281,12115],{"class":2145},[92,12283,4828],{"class":119},[92,12285,12287,12289,12292],{"class":94,"line":12286},51,[92,12288,12123],{"class":119},[92,12290,12291],{"class":2145},"schedule",[92,12293,4828],{"class":119},[92,12295,12297,12300,12302],{"class":94,"line":12296},52,[92,12298,12299],{"class":2145},"          rate",[92,12301,5263],{"class":119},[92,12303,12304],{"class":171},"rate(1 minute)\n",[92,12306,12308,12311,12313],{"class":94,"line":12307},53,[92,12309,12310],{"class":2145},"          input",[92,12312,5263],{"class":119},[92,12314,12315],{"class":171},"'\"schedule:run\"'\n",[11,12317,12318],{},"This is the most important file in the guide, so here is what each part does.",[11,12320,12321,12325,12326,12329,12330,12333,12334,12336,12337,12340],{},[10490,12322,12323],{},[15,12324,11868],{}," sets defaults for every function. ",[15,12327,12328],{},"runtime: provided.al2"," is the base Amazon Linux runtime that Bref's layers sit on. ",[15,12331,12332],{},"memorySize"," reads from ",[15,12335,11964],{},", and everything under ",[15,12338,12339],{},"environment"," becomes an env variable in all three functions.",[11,12342,12343,12347,12348,12351,12352,8762,12355,12358,12359,12362],{},[10490,12344,12345],{},[15,12346,11964],{}," holds per-stage values. ",[15,12349,12350],{},"serverless deploy --stage prod"," uses the ",[15,12353,12354],{},"prod",[15,12356,12357],{},"--stage staging"," uses ",[15,12360,12361],{},"staging",". Keeping every stage in one file is standard for a production app, so it is here from the start, not bolted on later.",[11,12364,12365,12370],{},[10490,12366,12367],{},[15,12368,12369],{},"web"," is your HTTP app.",[11016,12372,12373,12379,12385,12395,12401],{},[11019,12374,12375,12378],{},[15,12376,12377],{},"handler: public/index.php"," points Lambda at Laravel's front controller.",[11019,12380,12381,12384],{},[15,12382,12383],{},"runtime: php-83-fpm"," is the PHP-FPM runtime, the same model your local Nginx talks to.",[11019,12386,12387,12390,12391,12394],{},[15,12388,12389],{},"httpApi: '*'"," tells ",[10490,12392,12393],{},"API Gateway"," (the HTTP front door that invokes Lambda) to forward every path and method here.",[11019,12396,12397,12400],{},[15,12398,12399],{},"timeout: 28"," sits just under API Gateway's hard 29-second limit.",[11019,12402,12403,12406],{},[15,12404,12405],{},"BREF_BINARY_RESPONSES: '1'"," lets it return images and PDFs (Step 9 explains why).",[11,12408,12409,12414],{},[10490,12410,12411],{},[15,12412,12413],{},"worker"," processes queued jobs.",[11016,12416,12417,12427,12433],{},[11019,12418,12419,12420,12422,12423,12426],{},"It has no HTTP event. The ",[15,12421,12192],{}," event subscribes it to the queue, so ",[10490,12424,12425],{},"SQS"," (a managed message queue) invokes it when a job arrives.",[11019,12428,12429,12432],{},[15,12430,12431],{},"handler: ...QueueHandler"," is Bref's bridge that turns an SQS message into a normal Laravel job.",[11019,12434,12435,12438,12439,12442],{},[15,12436,12437],{},"batchSize: 1"," runs one job per invocation. ",[15,12440,12441],{},"maximumConcurrency: 5"," caps parallel workers so they do not overwhelm your database.",[11,12444,12445,12450],{},[10490,12446,12447],{},[15,12448,12449],{},"console"," runs artisan.",[11016,12452,12453,12459],{},[11019,12454,12455,12458],{},[15,12456,12457],{},"handler: artisan"," targets Laravel's console kernel.",[11019,12460,1792,12461,12463,12464,12467,12468,12471],{},[15,12462,12291],{}," event is ",[10490,12465,12466],{},"EventBridge"," (AWS's scheduler). Every minute it invokes the function with ",[15,12469,12470],{},"schedule:run",", Laravel's scheduler entry point. This replaces the cron line you would add on a normal server.",[11,12473,1792,12474,12477],{},[15,12475,12476],{},"arn: !GetAtt JobsQueue.Arn"," reference points at a queue you create in the next step.",[39,12479,12481],{"id":12480},"step-5-move-drivers-to-managed-services","Step 5: Move drivers to managed services",[11,12483,12484],{},"Set drivers by environment, never in code, so the same app still runs locally. Each block below shows its file on the first line.",[242,12486,12488],{"id":12487},"sessions-and-cache-dynamodb","Sessions and cache → DynamoDB",[11,12490,12491,12494],{},[10490,12492,12493],{},"DynamoDB"," is a managed NoSQL key-value store, a good fit for keyed data with an expiry.",[83,12496,12500],{"className":12497,"code":12498,"language":12499,"meta":88,"style":88},"language-dotenv shiki shiki-themes github-dark","# .env\nSESSION_DRIVER=dynamodb\nCACHE_STORE=dynamodb\nDYNAMODB_CACHE_TABLE=acme-app-cache\n","dotenv",[15,12501,12502,12507,12512,12517],{"__ignoreMap":88},[92,12503,12504],{"class":94,"line":95},[92,12505,12506],{},"# .env\n",[92,12508,12509],{"class":94,"line":106},[92,12510,12511],{},"SESSION_DRIVER=dynamodb\n",[92,12513,12514],{"class":94,"line":113},[92,12515,12516],{},"CACHE_STORE=dynamodb\n",[92,12518,12519],{"class":94,"line":138},[92,12520,12521],{},"DYNAMODB_CACHE_TABLE=acme-app-cache\n",[11,12523,12524,12525,12527,12528,12530,12531,12534],{},"Add the table to ",[15,12526,11836],{},". It needs a ",[15,12529,4142],{}," partition key and a TTL attribute ",[15,12532,12533],{},"expires_at",", which is what Laravel's DynamoDB store reads:",[83,12536,12538],{"className":11840,"code":12537,"language":11842,"meta":88,"style":88},"# serverless.yml (add a top-level resources: block)\nresources:\n  Resources:\n    CacheTable:\n      Type: AWS::DynamoDB::Table\n      Properties:\n        TableName: acme-app-cache\n        BillingMode: PAY_PER_REQUEST\n        AttributeDefinitions:\n          - { AttributeName: key, AttributeType: S }\n        KeySchema:\n          - { AttributeName: key, KeyType: HASH }\n        TimeToLiveSpecification:\n          AttributeName: expires_at\n          Enabled: true\n",[15,12539,12540,12545,12552,12559,12566,12576,12583,12593,12603,12610,12634,12641,12663,12670,12680],{"__ignoreMap":88},[92,12541,12542],{"class":94,"line":95},[92,12543,12544],{"class":134},"# serverless.yml (add a top-level resources: block)\n",[92,12546,12547,12550],{"class":94,"line":106},[92,12548,12549],{"class":2145},"resources",[92,12551,4828],{"class":119},[92,12553,12554,12557],{"class":94,"line":113},[92,12555,12556],{"class":2145},"  Resources",[92,12558,4828],{"class":119},[92,12560,12561,12564],{"class":94,"line":138},[92,12562,12563],{"class":2145},"    CacheTable",[92,12565,4828],{"class":119},[92,12567,12568,12571,12573],{"class":94,"line":143},[92,12569,12570],{"class":2145},"      Type",[92,12572,5263],{"class":119},[92,12574,12575],{"class":171},"AWS::DynamoDB::Table\n",[92,12577,12578,12581],{"class":94,"line":149},[92,12579,12580],{"class":2145},"      Properties",[92,12582,4828],{"class":119},[92,12584,12585,12588,12590],{"class":94,"line":155},[92,12586,12587],{"class":2145},"        TableName",[92,12589,5263],{"class":119},[92,12591,12592],{"class":171},"acme-app-cache\n",[92,12594,12595,12598,12600],{"class":94,"line":161},[92,12596,12597],{"class":2145},"        BillingMode",[92,12599,5263],{"class":119},[92,12601,12602],{"class":171},"PAY_PER_REQUEST\n",[92,12604,12605,12608],{"class":94,"line":166},[92,12606,12607],{"class":2145},"        AttributeDefinitions",[92,12609,4828],{"class":119},[92,12611,12612,12615,12618,12620,12622,12624,12627,12629,12632],{"class":94,"line":187},[92,12613,12614],{"class":119},"          - { ",[92,12616,12617],{"class":2145},"AttributeName",[92,12619,5263],{"class":119},[92,12621,4142],{"class":171},[92,12623,195],{"class":119},[92,12625,12626],{"class":2145},"AttributeType",[92,12628,5263],{"class":119},[92,12630,12631],{"class":171},"S",[92,12633,4506],{"class":119},[92,12635,12636,12639],{"class":94,"line":217},[92,12637,12638],{"class":2145},"        KeySchema",[92,12640,4828],{"class":119},[92,12642,12643,12645,12647,12649,12651,12653,12656,12658,12661],{"class":94,"line":712},[92,12644,12614],{"class":119},[92,12646,12617],{"class":2145},[92,12648,5263],{"class":119},[92,12650,4142],{"class":171},[92,12652,195],{"class":119},[92,12654,12655],{"class":2145},"KeyType",[92,12657,5263],{"class":119},[92,12659,12660],{"class":171},"HASH",[92,12662,4506],{"class":119},[92,12664,12665,12668],{"class":94,"line":730},[92,12666,12667],{"class":2145},"        TimeToLiveSpecification",[92,12669,4828],{"class":119},[92,12671,12672,12675,12677],{"class":94,"line":747},[92,12673,12674],{"class":2145},"          AttributeName",[92,12676,5263],{"class":119},[92,12678,12679],{"class":171},"expires_at\n",[92,12681,12682,12685,12687],{"class":94,"line":763},[92,12683,12684],{"class":2145},"          Enabled",[92,12686,5263],{"class":119},[92,12688,12689],{"class":102},"true\n",[242,12691,12693],{"id":12692},"queue-sqs","Queue → SQS",[83,12695,12697],{"className":12497,"code":12696,"language":12499,"meta":88,"style":88},"# .env\nQUEUE_CONNECTION=sqs\nSQS_PREFIX=https://sqs.ap-south-1.amazonaws.com/123456789012\nSQS_QUEUE=acme-app-jobs\n",[15,12698,12699,12703,12708,12713],{"__ignoreMap":88},[92,12700,12701],{"class":94,"line":95},[92,12702,12506],{},[92,12704,12705],{"class":94,"line":106},[92,12706,12707],{},"QUEUE_CONNECTION=sqs\n",[92,12709,12710],{"class":94,"line":113},[92,12711,12712],{},"SQS_PREFIX=https://sqs.ap-south-1.amazonaws.com/123456789012\n",[92,12714,12715],{"class":94,"line":138},[92,12716,12717],{},"SQS_QUEUE=acme-app-jobs\n",[11,12719,12720,12721,12724,12725,5185],{},"Add the queue and a dead-letter queue (a backup queue that catches jobs that fail repeatedly) under the same ",[15,12722,12723],{},"resources.Resources"," block, next to ",[15,12726,12727],{},"CacheTable",[83,12729,12731],{"className":11840,"code":12730,"language":11842,"meta":88,"style":88},"# serverless.yml (inside resources: > Resources:)\n    JobsQueue:\n      Type: AWS::SQS::Queue\n      Properties:\n        QueueName: acme-app-jobs\n        VisibilityTimeout: 360 # must exceed the worker timeout several times over\n        RedrivePolicy:\n          deadLetterTargetArn: !GetAtt JobsDLQ.Arn\n          maxReceiveCount: 3\n    JobsDLQ:\n      Type: AWS::SQS::Queue\n      Properties:\n        QueueName: acme-app-jobs-dlq\n",[15,12732,12733,12738,12745,12754,12760,12770,12783,12790,12802,12812,12819,12827,12833],{"__ignoreMap":88},[92,12734,12735],{"class":94,"line":95},[92,12736,12737],{"class":134},"# serverless.yml (inside resources: > Resources:)\n",[92,12739,12740,12743],{"class":94,"line":106},[92,12741,12742],{"class":2145},"    JobsQueue",[92,12744,4828],{"class":119},[92,12746,12747,12749,12751],{"class":94,"line":113},[92,12748,12570],{"class":2145},[92,12750,5263],{"class":119},[92,12752,12753],{"class":171},"AWS::SQS::Queue\n",[92,12755,12756,12758],{"class":94,"line":138},[92,12757,12580],{"class":2145},[92,12759,4828],{"class":119},[92,12761,12762,12765,12767],{"class":94,"line":143},[92,12763,12764],{"class":2145},"        QueueName",[92,12766,5263],{"class":119},[92,12768,12769],{"class":171},"acme-app-jobs\n",[92,12771,12772,12775,12777,12780],{"class":94,"line":149},[92,12773,12774],{"class":2145},"        VisibilityTimeout",[92,12776,5263],{"class":119},[92,12778,12779],{"class":102},"360",[92,12781,12782],{"class":134}," # must exceed the worker timeout several times over\n",[92,12784,12785,12788],{"class":94,"line":155},[92,12786,12787],{"class":2145},"        RedrivePolicy",[92,12789,4828],{"class":119},[92,12791,12792,12795,12797,12799],{"class":94,"line":161},[92,12793,12794],{"class":2145},"          deadLetterTargetArn",[92,12796,5263],{"class":119},[92,12798,12205],{"class":98},[92,12800,12801],{"class":171}," JobsDLQ.Arn\n",[92,12803,12804,12807,12809],{"class":94,"line":166},[92,12805,12806],{"class":2145},"          maxReceiveCount",[92,12808,5263],{"class":119},[92,12810,12811],{"class":102},"3\n",[92,12813,12814,12817],{"class":94,"line":187},[92,12815,12816],{"class":2145},"    JobsDLQ",[92,12818,4828],{"class":119},[92,12820,12821,12823,12825],{"class":94,"line":217},[92,12822,12570],{"class":2145},[92,12824,5263],{"class":119},[92,12826,12753],{"class":171},[92,12828,12829,12831],{"class":94,"line":712},[92,12830,12580],{"class":2145},[92,12832,4828],{"class":119},[92,12834,12835,12837,12839],{"class":94,"line":730},[92,12836,12764],{"class":2145},[92,12838,5263],{"class":119},[92,12840,12841],{"class":171},"acme-app-jobs-dlq\n",[11813,12843,12844],{},[11,12845,12846,12849,12850,12853],{},[10490,12847,12848],{},"Set the visibility timeout high."," It is how long a job stays hidden after a worker picks it up. If it expires mid-run, SQS gives the same job to a second worker and it runs twice. Use several times the worker ",[15,12851,12852],{},"timeout"," (here 60s, so 360).",[11813,12855,12856],{},[11,12857,12858,12861],{},[10490,12859,12860],{},"Do not use Horizon."," It needs a long-running process, which Lambda has no place for. The plain SQS driver plus Bref's worker gives you retries and the dead-letter queue instead.",[242,12863,12865],{"id":12864},"files-s3","Files → S3",[11,12867,12868,12871],{},[10490,12869,12870],{},"S3"," is AWS's managed file storage.",[83,12873,12875],{"className":12497,"code":12874,"language":12499,"meta":88,"style":88},"# .env\nFILESYSTEM_DISK=s3\nAWS_BUCKET=acme-app-uploads\nAWS_DEFAULT_REGION=ap-south-1\n",[15,12876,12877,12881,12886,12891],{"__ignoreMap":88},[92,12878,12879],{"class":94,"line":95},[92,12880,12506],{},[92,12882,12883],{"class":94,"line":106},[92,12884,12885],{},"FILESYSTEM_DISK=s3\n",[92,12887,12888],{"class":94,"line":113},[92,12889,12890],{},"AWS_BUCKET=acme-app-uploads\n",[92,12892,12893],{"class":94,"line":138},[92,12894,12895],{},"AWS_DEFAULT_REGION=ap-south-1\n",[11,12897,12898,12899,12901,12902,6339,12905,12908],{},"Do ",[10490,12900,5608],{}," set ",[15,12903,12904],{},"AWS_ACCESS_KEY_ID",[15,12906,12907],{},"AWS_SECRET_ACCESS_KEY",". The next callout explains why.",[11813,12910,12911,12938,12993],{},[11,12912,12913,12916,12917,195,12920,394,12923,12926,12927,834,12929,12932,12933,834,12935,12937],{},[10490,12914,12915],{},"The credential trap."," Lambda gives each function a temporary role credential (with a session token) through environment variables. Laravel's ",[15,12918,12919],{},"config/filesystems.php",[15,12921,12922],{},"config/queue.php",[15,12924,12925],{},"config/cache.php"," pass ",[15,12928,4142],{},[15,12930,12931],{},"secret"," to the AWS SDK but not the token, so calls fail with a signature error. Fix it: leave ",[15,12934,4142],{},[15,12936,12931],{}," empty on Lambda so the SDK reads the full role credential itself.",[83,12939,12941],{"className":85,"code":12940,"language":87,"meta":88,"style":88},"// config/filesystems.php, the s3 disk\n'key' => env('AWS_ACCESS_KEY_ID') ?: null,\n'secret' => env('AWS_SECRET_ACCESS_KEY') ?: null,\n",[15,12942,12943,12948,12971],{"__ignoreMap":88},[92,12944,12945],{"class":94,"line":95},[92,12946,12947],{"class":134},"// config/filesystems.php, the s3 disk\n",[92,12949,12950,12953,12955,12958,12960,12963,12965,12967,12969],{"class":94,"line":106},[92,12951,12952],{"class":171},"'key'",[92,12954,1019],{"class":98},[92,12956,12957],{"class":5161}," env",[92,12959,120],{"class":119},[92,12961,12962],{"class":171},"'AWS_ACCESS_KEY_ID'",[92,12964,683],{"class":119},[92,12966,1713],{"class":98},[92,12968,1031],{"class":102},[92,12970,4772],{"class":119},[92,12972,12973,12976,12978,12980,12982,12985,12987,12989,12991],{"class":94,"line":113},[92,12974,12975],{"class":171},"'secret'",[92,12977,1019],{"class":98},[92,12979,12957],{"class":5161},[92,12981,120],{"class":119},[92,12983,12984],{"class":171},"'AWS_SECRET_ACCESS_KEY'",[92,12986,683],{"class":119},[92,12988,1713],{"class":98},[92,12990,1031],{"class":102},[92,12992,4772],{"class":119},[11,12994,12995,12996,834,12998,13001],{},"Do the same for the ",[15,12997,12192],{},[15,12999,13000],{},"dynamodb"," blocks.",[242,13003,13005],{"id":13004},"logs-cloudwatch","Logs → CloudWatch",[11,13007,13008,13009,13012,13013,13015,13016,1524,13019,13022],{},"You already set ",[15,13010,13011],{},"LOG_CHANNEL=stderr"," in ",[15,13014,11836],{},". Lambda ships anything on ",[15,13017,13018],{},"stderr",[10490,13020,13021],{},"CloudWatch"," (AWS's log store). No log files, no extra config.",[242,13024,13026],{"id":13025},"give-the-functions-permission","Give the functions permission",[11,13028,13029,13030,13033,13034,5185],{},"The functions run under one execution role. Grant it access to the bucket and table you just created, by adding an ",[15,13031,13032],{},"iam"," block inside the existing ",[15,13035,11868],{},[83,13037,13039],{"className":11840,"code":13038,"language":11842,"meta":88,"style":88},"# serverless.yml (merge into the existing provider: block)\nprovider:\n  iam:\n    role:\n      statements:\n        - Effect: Allow\n          Action: [s3:PutObject, s3:GetObject, s3:DeleteObject]\n          Resource: arn:aws:s3:::acme-app-uploads/*\n        - Effect: Allow\n          Action: [dynamodb:GetItem, dynamodb:PutItem, dynamodb:DeleteItem, dynamodb:UpdateItem]\n          Resource: !GetAtt CacheTable.Arn\n",[15,13040,13041,13046,13052,13059,13066,13073,13086,13110,13120,13130,13156],{"__ignoreMap":88},[92,13042,13043],{"class":94,"line":95},[92,13044,13045],{"class":134},"# serverless.yml (merge into the existing provider: block)\n",[92,13047,13048,13050],{"class":94,"line":106},[92,13049,11868],{"class":2145},[92,13051,4828],{"class":119},[92,13053,13054,13057],{"class":94,"line":113},[92,13055,13056],{"class":2145},"  iam",[92,13058,4828],{"class":119},[92,13060,13061,13064],{"class":94,"line":138},[92,13062,13063],{"class":2145},"    role",[92,13065,4828],{"class":119},[92,13067,13068,13071],{"class":94,"line":143},[92,13069,13070],{"class":2145},"      statements",[92,13072,4828],{"class":119},[92,13074,13075,13078,13081,13083],{"class":94,"line":149},[92,13076,13077],{"class":119},"        - ",[92,13079,13080],{"class":2145},"Effect",[92,13082,5263],{"class":119},[92,13084,13085],{"class":171},"Allow\n",[92,13087,13088,13091,13094,13097,13099,13102,13104,13107],{"class":94,"line":155},[92,13089,13090],{"class":2145},"          Action",[92,13092,13093],{"class":119},": [",[92,13095,13096],{"class":171},"s3:PutObject",[92,13098,195],{"class":119},[92,13100,13101],{"class":171},"s3:GetObject",[92,13103,195],{"class":119},[92,13105,13106],{"class":171},"s3:DeleteObject",[92,13108,13109],{"class":119},"]\n",[92,13111,13112,13115,13117],{"class":94,"line":161},[92,13113,13114],{"class":2145},"          Resource",[92,13116,5263],{"class":119},[92,13118,13119],{"class":171},"arn:aws:s3:::acme-app-uploads/*\n",[92,13121,13122,13124,13126,13128],{"class":94,"line":166},[92,13123,13077],{"class":119},[92,13125,13080],{"class":2145},[92,13127,5263],{"class":119},[92,13129,13085],{"class":171},[92,13131,13132,13134,13136,13139,13141,13144,13146,13149,13151,13154],{"class":94,"line":187},[92,13133,13090],{"class":2145},[92,13135,13093],{"class":119},[92,13137,13138],{"class":171},"dynamodb:GetItem",[92,13140,195],{"class":119},[92,13142,13143],{"class":171},"dynamodb:PutItem",[92,13145,195],{"class":119},[92,13147,13148],{"class":171},"dynamodb:DeleteItem",[92,13150,195],{"class":119},[92,13152,13153],{"class":171},"dynamodb:UpdateItem",[92,13155,13109],{"class":119},[92,13157,13158,13160,13162,13164],{"class":94,"line":217},[92,13159,13114],{"class":2145},[92,13161,5263],{"class":119},[92,13163,12205],{"class":98},[92,13165,13166],{"class":171}," CacheTable.Arn\n",[242,13168,13170],{"id":13169},"the-complete-serverlessyml","The complete serverless.yml",[11,13172,13173,13174,13177,13178,13181],{},"You added several fragments above. Here is the whole file assembled, so you can check placement before deploying. You add the ",[15,13175,13176],{},"customDomain"," block (Step 10) and optional ",[15,13179,13180],{},"layers"," (Step 11) later.",[83,13183,13185],{"className":11840,"code":13184,"language":11842,"meta":88,"style":88},"# serverless.yml\nservice: acme-app\n\nprovider:\n  name: aws\n  region: ap-south-1\n  runtime: provided.al2\n  memorySize: ${param:memory}\n  environment:\n    APP_ENV: production\n    APP_DEBUG: 'false'\n    LOG_CHANNEL: stderr\n  iam:\n    role:\n      statements:\n        - Effect: Allow\n          Action: [s3:PutObject, s3:GetObject, s3:DeleteObject]\n          Resource: arn:aws:s3:::acme-app-uploads/*\n        - Effect: Allow\n          Action: [dynamodb:GetItem, dynamodb:PutItem, dynamodb:DeleteItem, dynamodb:UpdateItem]\n          Resource: !GetAtt CacheTable.Arn\n\nparams:\n  prod:\n    memory: 1024\n    domain: example.com\n  staging:\n    memory: 512\n    domain: staging.example.com\n\nplugins:\n  - ./vendor/bref/bref\n\nfunctions:\n  web:\n    handler: public/index.php\n    runtime: php-83-fpm\n    timeout: 28\n    environment:\n      BREF_BINARY_RESPONSES: '1'\n    events:\n      - httpApi: '*'\n\n  worker:\n    handler: Bref\\LaravelBridge\\Queue\\QueueHandler\n    runtime: php-83\n    timeout: 60\n    events:\n      - sqs:\n          arn: !GetAtt JobsQueue.Arn\n          batchSize: 1\n          maximumConcurrency: 5\n\n  console:\n    handler: artisan\n    runtime: php-83-console\n    timeout: 120\n    events:\n      - schedule:\n          rate: rate(1 minute)\n          input: '\"schedule:run\"'\n\nresources:\n  Resources:\n    CacheTable:\n      Type: AWS::DynamoDB::Table\n      Properties:\n        TableName: acme-app-cache\n        BillingMode: PAY_PER_REQUEST\n        AttributeDefinitions:\n          - { AttributeName: key, AttributeType: S }\n        KeySchema:\n          - { AttributeName: key, KeyType: HASH }\n        TimeToLiveSpecification:\n          AttributeName: expires_at\n          Enabled: true\n    JobsQueue:\n      Type: AWS::SQS::Queue\n      Properties:\n        QueueName: acme-app-jobs\n        VisibilityTimeout: 360\n        RedrivePolicy:\n          deadLetterTargetArn: !GetAtt JobsDLQ.Arn\n          maxReceiveCount: 3\n    JobsDLQ:\n      Type: AWS::SQS::Queue\n      Properties:\n        QueueName: acme-app-jobs-dlq\n",[15,13186,13187,13191,13199,13203,13209,13217,13225,13233,13242,13248,13256,13264,13272,13278,13284,13290,13300,13318,13326,13336,13358,13368,13372,13378,13384,13392,13400,13406,13414,13422,13426,13432,13438,13442,13448,13454,13462,13470,13478,13484,13492,13498,13508,13512,13518,13526,13534,13542,13548,13556,13566,13574,13582,13586,13593,13602,13611,13620,13627,13636,13645,13654,13659,13666,13673,13680,13689,13696,13705,13714,13721,13742,13749,13770,13777,13786,13795,13802,13811,13818,13827,13837,13844,13855,13864,13871,13880,13887],{"__ignoreMap":88},[92,13188,13189],{"class":94,"line":95},[92,13190,11849],{"class":134},[92,13192,13193,13195,13197],{"class":94,"line":106},[92,13194,11854],{"class":2145},[92,13196,5263],{"class":119},[92,13198,11859],{"class":171},[92,13200,13201],{"class":94,"line":113},[92,13202,110],{"emptyLinePlaceholder":109},[92,13204,13205,13207],{"class":94,"line":138},[92,13206,11868],{"class":2145},[92,13208,4828],{"class":119},[92,13210,13211,13213,13215],{"class":94,"line":143},[92,13212,11875],{"class":2145},[92,13214,5263],{"class":119},[92,13216,11880],{"class":171},[92,13218,13219,13221,13223],{"class":94,"line":149},[92,13220,11885],{"class":2145},[92,13222,5263],{"class":119},[92,13224,11890],{"class":171},[92,13226,13227,13229,13231],{"class":94,"line":155},[92,13228,11895],{"class":2145},[92,13230,5263],{"class":119},[92,13232,11900],{"class":171},[92,13234,13235,13237,13239],{"class":94,"line":161},[92,13236,11905],{"class":2145},[92,13238,5263],{"class":119},[92,13240,13241],{"class":171},"${param:memory}\n",[92,13243,13244,13246],{"class":94,"line":166},[92,13245,11918],{"class":2145},[92,13247,4828],{"class":119},[92,13249,13250,13252,13254],{"class":94,"line":187},[92,13251,11925],{"class":2145},[92,13253,5263],{"class":119},[92,13255,11930],{"class":171},[92,13257,13258,13260,13262],{"class":94,"line":217},[92,13259,11935],{"class":2145},[92,13261,5263],{"class":119},[92,13263,11940],{"class":171},[92,13265,13266,13268,13270],{"class":94,"line":712},[92,13267,11945],{"class":2145},[92,13269,5263],{"class":119},[92,13271,11950],{"class":171},[92,13273,13274,13276],{"class":94,"line":730},[92,13275,13056],{"class":2145},[92,13277,4828],{"class":119},[92,13279,13280,13282],{"class":94,"line":747},[92,13281,13063],{"class":2145},[92,13283,4828],{"class":119},[92,13285,13286,13288],{"class":94,"line":763},[92,13287,13070],{"class":2145},[92,13289,4828],{"class":119},[92,13291,13292,13294,13296,13298],{"class":94,"line":780},[92,13293,13077],{"class":119},[92,13295,13080],{"class":2145},[92,13297,5263],{"class":119},[92,13299,13085],{"class":171},[92,13301,13302,13304,13306,13308,13310,13312,13314,13316],{"class":94,"line":785},[92,13303,13090],{"class":2145},[92,13305,13093],{"class":119},[92,13307,13096],{"class":171},[92,13309,195],{"class":119},[92,13311,13101],{"class":171},[92,13313,195],{"class":119},[92,13315,13106],{"class":171},[92,13317,13109],{"class":119},[92,13319,13320,13322,13324],{"class":94,"line":2585},[92,13321,13114],{"class":2145},[92,13323,5263],{"class":119},[92,13325,13119],{"class":171},[92,13327,13328,13330,13332,13334],{"class":94,"line":2605},[92,13329,13077],{"class":119},[92,13331,13080],{"class":2145},[92,13333,5263],{"class":119},[92,13335,13085],{"class":171},[92,13337,13338,13340,13342,13344,13346,13348,13350,13352,13354,13356],{"class":94,"line":2634},[92,13339,13090],{"class":2145},[92,13341,13093],{"class":119},[92,13343,13138],{"class":171},[92,13345,195],{"class":119},[92,13347,13143],{"class":171},[92,13349,195],{"class":119},[92,13351,13148],{"class":171},[92,13353,195],{"class":119},[92,13355,13153],{"class":171},[92,13357,13109],{"class":119},[92,13359,13360,13362,13364,13366],{"class":94,"line":2651},[92,13361,13114],{"class":2145},[92,13363,5263],{"class":119},[92,13365,12205],{"class":98},[92,13367,13166],{"class":171},[92,13369,13370],{"class":94,"line":2671},[92,13371,110],{"emptyLinePlaceholder":109},[92,13373,13374,13376],{"class":94,"line":2676},[92,13375,11964],{"class":2145},[92,13377,4828],{"class":119},[92,13379,13380,13382],{"class":94,"line":2697},[92,13381,11971],{"class":2145},[92,13383,4828],{"class":119},[92,13385,13386,13388,13390],{"class":94,"line":2726},[92,13387,11978],{"class":2145},[92,13389,5263],{"class":119},[92,13391,11983],{"class":102},[92,13393,13394,13396,13398],{"class":94,"line":2755},[92,13395,11988],{"class":2145},[92,13397,5263],{"class":119},[92,13399,11993],{"class":171},[92,13401,13402,13404],{"class":94,"line":2776},[92,13403,11998],{"class":2145},[92,13405,4828],{"class":119},[92,13407,13408,13410,13412],{"class":94,"line":12060},[92,13409,11978],{"class":2145},[92,13411,5263],{"class":119},[92,13413,12009],{"class":102},[92,13415,13416,13418,13420],{"class":94,"line":12071},[92,13417,11988],{"class":2145},[92,13419,5263],{"class":119},[92,13421,12018],{"class":171},[92,13423,13424],{"class":94,"line":12082},[92,13425,110],{"emptyLinePlaceholder":109},[92,13427,13428,13430],{"class":94,"line":12093},[92,13429,12027],{"class":2145},[92,13431,4828],{"class":119},[92,13433,13434,13436],{"class":94,"line":12101},[92,13435,12034],{"class":119},[92,13437,12037],{"class":171},[92,13439,13440],{"class":94,"line":12112},[92,13441,110],{"emptyLinePlaceholder":109},[92,13443,13444,13446],{"class":94,"line":12120},[92,13445,5124],{"class":2145},[92,13447,4828],{"class":119},[92,13449,13450,13452],{"class":94,"line":12134},[92,13451,12052],{"class":2145},[92,13453,4828],{"class":119},[92,13455,13456,13458,13460],{"class":94,"line":12139},[92,13457,12063],{"class":2145},[92,13459,5263],{"class":119},[92,13461,12068],{"class":171},[92,13463,13464,13466,13468],{"class":94,"line":12150},[92,13465,12074],{"class":2145},[92,13467,5263],{"class":119},[92,13469,12079],{"class":171},[92,13471,13472,13474,13476],{"class":94,"line":12160},[92,13473,12085],{"class":2145},[92,13475,5263],{"class":119},[92,13477,12090],{"class":102},[92,13479,13480,13482],{"class":94,"line":12170},[92,13481,12096],{"class":2145},[92,13483,4828],{"class":119},[92,13485,13486,13488,13490],{"class":94,"line":12180},[92,13487,12104],{"class":2145},[92,13489,5263],{"class":119},[92,13491,12109],{"class":171},[92,13493,13494,13496],{"class":94,"line":12187},[92,13495,12115],{"class":2145},[92,13497,4828],{"class":119},[92,13499,13500,13502,13504,13506],{"class":94,"line":12197},[92,13501,12123],{"class":119},[92,13503,12126],{"class":2145},[92,13505,5263],{"class":119},[92,13507,12131],{"class":171},[92,13509,13510],{"class":94,"line":12211},[92,13511,110],{"emptyLinePlaceholder":109},[92,13513,13514,13516],{"class":94,"line":12222},[92,13515,12142],{"class":2145},[92,13517,4828],{"class":119},[92,13519,13520,13522,13524],{"class":94,"line":12233},[92,13521,12063],{"class":2145},[92,13523,5263],{"class":119},[92,13525,12157],{"class":171},[92,13527,13528,13530,13532],{"class":94,"line":12238},[92,13529,12074],{"class":2145},[92,13531,5263],{"class":119},[92,13533,12167],{"class":171},[92,13535,13536,13538,13540],{"class":94,"line":12249},[92,13537,12085],{"class":2145},[92,13539,5263],{"class":119},[92,13541,12177],{"class":102},[92,13543,13544,13546],{"class":94,"line":12259},[92,13545,12115],{"class":2145},[92,13547,4828],{"class":119},[92,13549,13550,13552,13554],{"class":94,"line":12269},[92,13551,12123],{"class":119},[92,13553,12192],{"class":2145},[92,13555,4828],{"class":119},[92,13557,13558,13560,13562,13564],{"class":94,"line":12279},[92,13559,12200],{"class":2145},[92,13561,5263],{"class":119},[92,13563,12205],{"class":98},[92,13565,12208],{"class":171},[92,13567,13568,13570,13572],{"class":94,"line":12286},[92,13569,12214],{"class":2145},[92,13571,5263],{"class":119},[92,13573,12219],{"class":102},[92,13575,13576,13578,13580],{"class":94,"line":12296},[92,13577,12225],{"class":2145},[92,13579,5263],{"class":119},[92,13581,12230],{"class":102},[92,13583,13584],{"class":94,"line":12307},[92,13585,110],{"emptyLinePlaceholder":109},[92,13587,13589,13591],{"class":94,"line":13588},54,[92,13590,12241],{"class":2145},[92,13592,4828],{"class":119},[92,13594,13596,13598,13600],{"class":94,"line":13595},55,[92,13597,12063],{"class":2145},[92,13599,5263],{"class":119},[92,13601,12256],{"class":171},[92,13603,13605,13607,13609],{"class":94,"line":13604},56,[92,13606,12074],{"class":2145},[92,13608,5263],{"class":119},[92,13610,12266],{"class":171},[92,13612,13614,13616,13618],{"class":94,"line":13613},57,[92,13615,12085],{"class":2145},[92,13617,5263],{"class":119},[92,13619,12276],{"class":102},[92,13621,13623,13625],{"class":94,"line":13622},58,[92,13624,12115],{"class":2145},[92,13626,4828],{"class":119},[92,13628,13630,13632,13634],{"class":94,"line":13629},59,[92,13631,12123],{"class":119},[92,13633,12291],{"class":2145},[92,13635,4828],{"class":119},[92,13637,13639,13641,13643],{"class":94,"line":13638},60,[92,13640,12299],{"class":2145},[92,13642,5263],{"class":119},[92,13644,12304],{"class":171},[92,13646,13648,13650,13652],{"class":94,"line":13647},61,[92,13649,12310],{"class":2145},[92,13651,5263],{"class":119},[92,13653,12315],{"class":171},[92,13655,13657],{"class":94,"line":13656},62,[92,13658,110],{"emptyLinePlaceholder":109},[92,13660,13662,13664],{"class":94,"line":13661},63,[92,13663,12549],{"class":2145},[92,13665,4828],{"class":119},[92,13667,13669,13671],{"class":94,"line":13668},64,[92,13670,12556],{"class":2145},[92,13672,4828],{"class":119},[92,13674,13676,13678],{"class":94,"line":13675},65,[92,13677,12563],{"class":2145},[92,13679,4828],{"class":119},[92,13681,13683,13685,13687],{"class":94,"line":13682},66,[92,13684,12570],{"class":2145},[92,13686,5263],{"class":119},[92,13688,12575],{"class":171},[92,13690,13692,13694],{"class":94,"line":13691},67,[92,13693,12580],{"class":2145},[92,13695,4828],{"class":119},[92,13697,13699,13701,13703],{"class":94,"line":13698},68,[92,13700,12587],{"class":2145},[92,13702,5263],{"class":119},[92,13704,12592],{"class":171},[92,13706,13708,13710,13712],{"class":94,"line":13707},69,[92,13709,12597],{"class":2145},[92,13711,5263],{"class":119},[92,13713,12602],{"class":171},[92,13715,13717,13719],{"class":94,"line":13716},70,[92,13718,12607],{"class":2145},[92,13720,4828],{"class":119},[92,13722,13724,13726,13728,13730,13732,13734,13736,13738,13740],{"class":94,"line":13723},71,[92,13725,12614],{"class":119},[92,13727,12617],{"class":2145},[92,13729,5263],{"class":119},[92,13731,4142],{"class":171},[92,13733,195],{"class":119},[92,13735,12626],{"class":2145},[92,13737,5263],{"class":119},[92,13739,12631],{"class":171},[92,13741,4506],{"class":119},[92,13743,13745,13747],{"class":94,"line":13744},72,[92,13746,12638],{"class":2145},[92,13748,4828],{"class":119},[92,13750,13752,13754,13756,13758,13760,13762,13764,13766,13768],{"class":94,"line":13751},73,[92,13753,12614],{"class":119},[92,13755,12617],{"class":2145},[92,13757,5263],{"class":119},[92,13759,4142],{"class":171},[92,13761,195],{"class":119},[92,13763,12655],{"class":2145},[92,13765,5263],{"class":119},[92,13767,12660],{"class":171},[92,13769,4506],{"class":119},[92,13771,13773,13775],{"class":94,"line":13772},74,[92,13774,12667],{"class":2145},[92,13776,4828],{"class":119},[92,13778,13780,13782,13784],{"class":94,"line":13779},75,[92,13781,12674],{"class":2145},[92,13783,5263],{"class":119},[92,13785,12679],{"class":171},[92,13787,13789,13791,13793],{"class":94,"line":13788},76,[92,13790,12684],{"class":2145},[92,13792,5263],{"class":119},[92,13794,12689],{"class":102},[92,13796,13798,13800],{"class":94,"line":13797},77,[92,13799,12742],{"class":2145},[92,13801,4828],{"class":119},[92,13803,13805,13807,13809],{"class":94,"line":13804},78,[92,13806,12570],{"class":2145},[92,13808,5263],{"class":119},[92,13810,12753],{"class":171},[92,13812,13814,13816],{"class":94,"line":13813},79,[92,13815,12580],{"class":2145},[92,13817,4828],{"class":119},[92,13819,13821,13823,13825],{"class":94,"line":13820},80,[92,13822,12764],{"class":2145},[92,13824,5263],{"class":119},[92,13826,12769],{"class":171},[92,13828,13830,13832,13834],{"class":94,"line":13829},81,[92,13831,12774],{"class":2145},[92,13833,5263],{"class":119},[92,13835,13836],{"class":102},"360\n",[92,13838,13840,13842],{"class":94,"line":13839},82,[92,13841,12787],{"class":2145},[92,13843,4828],{"class":119},[92,13845,13847,13849,13851,13853],{"class":94,"line":13846},83,[92,13848,12794],{"class":2145},[92,13850,5263],{"class":119},[92,13852,12205],{"class":98},[92,13854,12801],{"class":171},[92,13856,13858,13860,13862],{"class":94,"line":13857},84,[92,13859,12806],{"class":2145},[92,13861,5263],{"class":119},[92,13863,12811],{"class":102},[92,13865,13867,13869],{"class":94,"line":13866},85,[92,13868,12816],{"class":2145},[92,13870,4828],{"class":119},[92,13872,13874,13876,13878],{"class":94,"line":13873},86,[92,13875,12570],{"class":2145},[92,13877,5263],{"class":119},[92,13879,12753],{"class":171},[92,13881,13883,13885],{"class":94,"line":13882},87,[92,13884,12580],{"class":2145},[92,13886,4828],{"class":119},[92,13888,13890,13892,13894],{"class":94,"line":13889},88,[92,13891,12764],{"class":2145},[92,13893,5263],{"class":119},[92,13895,12841],{"class":171},[39,13897,13899],{"id":13898},"step-6-set-environment-variables-and-secrets","Step 6: Set environment variables and secrets",[11,13901,13902,13903,13906,13907,13909,13910,394,13912,13915,13916,13919,13920,13923],{},"On a normal server, Laravel reads config from a ",[15,13904,13905],{},".env"," file. There is no ",[15,13908,13905],{}," on Lambda, so each function reads real environment variables that you set in ",[15,13911,11836],{},[15,13913,13914],{},"env()"," reads them exactly as before. Non-secret values can sit inline; secrets like ",[15,13917,13918],{},"APP_KEY"," and the database password must not live in Git, so store them in ",[10490,13921,13922],{},"SSM Parameter Store"," (AWS's config and secret store) and reference them.",[11074,13925,13926],{},[11019,13927,13928,13929,5185],{},"Put each secret in SSM once per stage, as a ",[15,13930,13931],{},"SecureString",[83,13933,13935],{"className":11136,"code":13934,"language":11138,"meta":88,"style":88},"aws ssm put-parameter --name /acme-app/prod/APP_KEY --type SecureString --value 'base64:your-app-key'\naws ssm put-parameter --name /acme-app/prod/DB_PASSWORD --type SecureString --value 'your-db-password'\n",[15,13936,13937,13966],{"__ignoreMap":88},[92,13938,13939,13942,13945,13948,13951,13954,13957,13960,13963],{"class":94,"line":95},[92,13940,13941],{"class":5161},"aws",[92,13943,13944],{"class":171}," ssm",[92,13946,13947],{"class":171}," put-parameter",[92,13949,13950],{"class":102}," --name",[92,13952,13953],{"class":171}," /acme-app/prod/APP_KEY",[92,13955,13956],{"class":102}," --type",[92,13958,13959],{"class":171}," SecureString",[92,13961,13962],{"class":102}," --value",[92,13964,13965],{"class":171}," 'base64:your-app-key'\n",[92,13967,13968,13970,13972,13974,13976,13979,13981,13983,13985],{"class":94,"line":106},[92,13969,13941],{"class":5161},[92,13971,13944],{"class":171},[92,13973,13947],{"class":171},[92,13975,13950],{"class":102},[92,13977,13978],{"class":171}," /acme-app/prod/DB_PASSWORD",[92,13980,13956],{"class":102},[92,13982,13959],{"class":171},[92,13984,13962],{"class":102},[92,13986,13987],{"class":171}," 'your-db-password'\n",[11,13989,13990,13991,13993],{},"(Single-quote the value so the shell does not expand a ",[15,13992,251],{},".)",[11074,13995,13996],{"start":106},[11019,13997,13998,13999,14001,14002,14005,14006,14009],{},"Reference them in ",[15,14000,11836],{},", next to the non-secret values already in ",[15,14003,14004],{},"provider.environment",". ",[15,14007,14008],{},"${sls:stage}"," picks the parameter for the stage you deploy:",[83,14011,14013],{"className":11840,"code":14012,"language":11842,"meta":88,"style":88},"# serverless.yml (expand provider.environment)\nprovider:\n  environment:\n    APP_ENV: production\n    APP_DEBUG: 'false'\n    LOG_CHANNEL: stderr\n    APP_KEY: ${ssm:/acme-app/${sls:stage}/APP_KEY}\n    DB_CONNECTION: mysql\n    DB_HOST: your-db-host.example.com\n    DB_DATABASE: acme\n    DB_USERNAME: acme\n    DB_PASSWORD: ${ssm:/acme-app/${sls:stage}/DB_PASSWORD}\n",[15,14014,14015,14020,14026,14032,14040,14048,14056,14066,14076,14086,14096,14105],{"__ignoreMap":88},[92,14016,14017],{"class":94,"line":95},[92,14018,14019],{"class":134},"# serverless.yml (expand provider.environment)\n",[92,14021,14022,14024],{"class":94,"line":106},[92,14023,11868],{"class":2145},[92,14025,4828],{"class":119},[92,14027,14028,14030],{"class":94,"line":113},[92,14029,11918],{"class":2145},[92,14031,4828],{"class":119},[92,14033,14034,14036,14038],{"class":94,"line":138},[92,14035,11925],{"class":2145},[92,14037,5263],{"class":119},[92,14039,11930],{"class":171},[92,14041,14042,14044,14046],{"class":94,"line":143},[92,14043,11935],{"class":2145},[92,14045,5263],{"class":119},[92,14047,11940],{"class":171},[92,14049,14050,14052,14054],{"class":94,"line":149},[92,14051,11945],{"class":2145},[92,14053,5263],{"class":119},[92,14055,11950],{"class":171},[92,14057,14058,14061,14063],{"class":94,"line":155},[92,14059,14060],{"class":2145},"    APP_KEY",[92,14062,5263],{"class":119},[92,14064,14065],{"class":171},"${ssm:/acme-app/${sls:stage}/APP_KEY}\n",[92,14067,14068,14071,14073],{"class":94,"line":161},[92,14069,14070],{"class":2145},"    DB_CONNECTION",[92,14072,5263],{"class":119},[92,14074,14075],{"class":171},"mysql\n",[92,14077,14078,14081,14083],{"class":94,"line":166},[92,14079,14080],{"class":2145},"    DB_HOST",[92,14082,5263],{"class":119},[92,14084,14085],{"class":171},"your-db-host.example.com\n",[92,14087,14088,14091,14093],{"class":94,"line":187},[92,14089,14090],{"class":2145},"    DB_DATABASE",[92,14092,5263],{"class":119},[92,14094,14095],{"class":171},"acme\n",[92,14097,14098,14101,14103],{"class":94,"line":217},[92,14099,14100],{"class":2145},"    DB_USERNAME",[92,14102,5263],{"class":119},[92,14104,14095],{"class":171},[92,14106,14107,14110,14112],{"class":94,"line":712},[92,14108,14109],{"class":2145},"    DB_PASSWORD",[92,14111,5263],{"class":119},[92,14113,14114],{"class":171},"${ssm:/acme-app/${sls:stage}/DB_PASSWORD}\n",[11,14116,14117,14118,14121],{},"Serverless resolves ",[15,14119,14120],{},"${ssm:...}"," at deploy time and bakes the values into the function's environment. The running function reads plain env variables, so it never needs SSM access itself; only the deploy identity does (Step 7 grants that).",[11813,14123,14124],{},[11,14125,14126,14129,14130,14132,14133,14135],{},[10490,14127,14128],{},"Why this matters:"," Miss this and the app boots on Lambda with no ",[15,14131,13918],{}," or database config and returns a 500. The ",[15,14134,13905],{}," you use locally does not travel to Lambda; these variables replace it.",[11813,14137,14138],{},[11,14139,14140,14143,14144,13012,14147,14149,14150,14153],{},[10490,14141,14142],{},"Simpler alternative."," To keep secrets in GitHub instead, reference ",[15,14145,14146],{},"${env:APP_KEY}",[15,14148,11836],{}," and pass the values to the deploy step in CI (Step 12) with an ",[15,14151,14152],{},"env:"," block. SSM keeps secrets inside AWS and out of your CI provider, which is why it is the default here.",[39,14155,14157],{"id":14156},"step-7-create-the-aws-deploy-user","Step 7: Create the AWS deploy user",[11,14159,14160,14163],{},[15,14161,14162],{},"serverless deploy"," needs AWS credentials of its own. These are separate from the function execution role above.",[11074,14165,14166,14173],{},[11019,14167,14168,14169,14172],{},"In the AWS IAM console, create a user ",[15,14170,14171],{},"acme-deploy"," with programmatic access (or an IAM Identity Center permission set for SSO).",[11019,14174,14175,14176,14179,14180,14183],{},"Attach the policy below. Paste it as an ",[10490,14177,14178],{},"inline policy"," on that user in the IAM console; it is not a file in your project. Start broad, then tighten to ",[15,14181,14182],{},"acme-app-*"," once your first deploy works.",[83,14185,14188],{"className":14186,"code":14187,"language":9672,"meta":88,"style":88},"language-json shiki shiki-themes github-dark","{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [{\n    \"Effect\": \"Allow\",\n    \"Action\": [\n      \"cloudformation:*\", \"lambda:*\", \"apigateway:*\", \"iam:*\",\n      \"s3:*\", \"sqs:*\", \"dynamodb:*\", \"events:*\", \"logs:*\",\n      \"ssm:GetParameter\", \"ssm:GetParameters\",\n      \"acm:DescribeCertificate\", \"acm:ListCertificates\"\n    ],\n    \"Resource\": \"*\"\n  }]\n}\n",[15,14189,14190,14194,14206,14214,14226,14234,14256,14283,14295,14305,14310,14320,14325],{"__ignoreMap":88},[92,14191,14192],{"class":94,"line":95},[92,14193,11212],{"class":119},[92,14195,14196,14199,14201,14204],{"class":94,"line":106},[92,14197,14198],{"class":102},"  \"Version\"",[92,14200,5263],{"class":119},[92,14202,14203],{"class":171},"\"2012-10-17\"",[92,14205,4772],{"class":119},[92,14207,14208,14211],{"class":94,"line":113},[92,14209,14210],{"class":102},"  \"Statement\"",[92,14212,14213],{"class":119},": [{\n",[92,14215,14216,14219,14221,14224],{"class":94,"line":138},[92,14217,14218],{"class":102},"    \"Effect\"",[92,14220,5263],{"class":119},[92,14222,14223],{"class":171},"\"Allow\"",[92,14225,4772],{"class":119},[92,14227,14228,14231],{"class":94,"line":143},[92,14229,14230],{"class":102},"    \"Action\"",[92,14232,14233],{"class":119},": [\n",[92,14235,14236,14239,14241,14244,14246,14249,14251,14254],{"class":94,"line":149},[92,14237,14238],{"class":171},"      \"cloudformation:*\"",[92,14240,195],{"class":119},[92,14242,14243],{"class":171},"\"lambda:*\"",[92,14245,195],{"class":119},[92,14247,14248],{"class":171},"\"apigateway:*\"",[92,14250,195],{"class":119},[92,14252,14253],{"class":171},"\"iam:*\"",[92,14255,4772],{"class":119},[92,14257,14258,14261,14263,14266,14268,14271,14273,14276,14278,14281],{"class":94,"line":155},[92,14259,14260],{"class":171},"      \"s3:*\"",[92,14262,195],{"class":119},[92,14264,14265],{"class":171},"\"sqs:*\"",[92,14267,195],{"class":119},[92,14269,14270],{"class":171},"\"dynamodb:*\"",[92,14272,195],{"class":119},[92,14274,14275],{"class":171},"\"events:*\"",[92,14277,195],{"class":119},[92,14279,14280],{"class":171},"\"logs:*\"",[92,14282,4772],{"class":119},[92,14284,14285,14288,14290,14293],{"class":94,"line":161},[92,14286,14287],{"class":171},"      \"ssm:GetParameter\"",[92,14289,195],{"class":119},[92,14291,14292],{"class":171},"\"ssm:GetParameters\"",[92,14294,4772],{"class":119},[92,14296,14297,14300,14302],{"class":94,"line":166},[92,14298,14299],{"class":171},"      \"acm:DescribeCertificate\"",[92,14301,195],{"class":119},[92,14303,14304],{"class":171},"\"acm:ListCertificates\"\n",[92,14306,14307],{"class":94,"line":187},[92,14308,14309],{"class":119},"    ],\n",[92,14311,14312,14315,14317],{"class":94,"line":217},[92,14313,14314],{"class":102},"    \"Resource\"",[92,14316,5263],{"class":119},[92,14318,14319],{"class":171},"\"*\"\n",[92,14321,14322],{"class":94,"line":712},[92,14323,14324],{"class":119},"  }]\n",[92,14326,14327],{"class":94,"line":730},[92,14328,4711],{"class":119},[11074,14330,14331],{"start":113},[11019,14332,14333],{},"Save the credentials as a local profile so the CLI can read them:",[83,14335,14337],{"className":11136,"code":14336,"language":11138,"meta":88,"style":88},"aws configure --profile acme-deploy # paste the access key and secret\nexport AWS_PROFILE=acme-deploy\n",[15,14338,14339,14355],{"__ignoreMap":88},[92,14340,14341,14343,14346,14349,14352],{"class":94,"line":95},[92,14342,13941],{"class":5161},[92,14344,14345],{"class":171}," configure",[92,14347,14348],{"class":102}," --profile",[92,14350,14351],{"class":171}," acme-deploy",[92,14353,14354],{"class":134}," # paste the access key and secret\n",[92,14356,14357,14360,14363,14365],{"class":94,"line":106},[92,14358,14359],{"class":98},"export",[92,14361,14362],{"class":119}," AWS_PROFILE",[92,14364,126],{"class":98},[92,14366,14367],{"class":119},"acme-deploy\n",[11813,14369,14370],{},[11,14371,14372,14375,14376,14005,14378,14381,14382,14385],{},[10490,14373,14374],{},"Deploy keys never go in the app."," They live only on your machine or in CI. Lambda uses its own role at runtime, so keep these out of ",[15,14377,13905],{},[15,14379,14380],{},"iam:*"," is in the policy because the deploy creates that execution role for you, and ",[15,14383,14384],{},"ssm:GetParameter"," lets it resolve the secrets from Step 6.",[39,14387,14389],{"id":14388},"step-8-deploy-and-verify","Step 8: Deploy and verify",[83,14391,14393],{"className":11136,"code":14392,"language":11138,"meta":88,"style":88},"serverless deploy --stage prod\n",[15,14394,14395],{"__ignoreMap":88},[92,14396,14397,14399,14402,14405],{"class":94,"line":95},[92,14398,11827],{"class":5161},[92,14400,14401],{"class":171}," deploy",[92,14403,14404],{"class":102}," --stage",[92,14406,14407],{"class":171}," prod\n",[11,14409,14410,14411,14414],{},"The output prints the API Gateway URL, like ",[15,14412,14413],{},"https://abc123.execute-api.ap-south-1.amazonaws.com",". Verify every part:",[4068,14416,14417,14430],{},[4071,14418,14419],{},[4074,14420,14421,14424,14427],{},[4077,14422,14423],{},"Check",[4077,14425,14426],{},"Command",[4077,14428,14429],{},"Expected",[4090,14431,14432,14447,14464,14477],{},[4074,14433,14434,14437,14442],{},[4095,14435,14436],{},"Web",[4095,14438,14439],{},[15,14440,14441],{},"curl \u003Curl>/health",[4095,14443,14444],{},[15,14445,14446],{},"{\"ok\":true,...}",[4074,14448,14449,14452,14458],{},[4095,14450,14451],{},"Cache + session",[4095,14453,14454,14457],{},[15,14455,14456],{},"curl \u003Curl>/counter"," twice",[4095,14459,14460,14463],{},[15,14461,14462],{},"hits"," increases (DynamoDB works)",[4074,14465,14466,14469,14474],{},[4095,14467,14468],{},"Queue",[4095,14470,14471],{},[15,14472,14473],{},"curl -F file=@photo.jpg \u003Curl>/uploads",[4095,14475,14476],{},"file in S3, \"Processing upload\" in CloudWatch",[4074,14478,14479,14481,14484],{},[4095,14480,11429],{},[4095,14482,14483],{},"wait 1 min, check console logs",[4095,14485,14486],{},"heartbeat line appears",[11813,14488,14489],{},[11,14490,14491,14494,14495,14498],{},[10490,14492,14493],{},"Keep the package under 250 MB."," Lambda's unzipped limit is 250 MB, and ",[15,14496,14497],{},"aws/aws-sdk-php"," alone can use over 100 MB. A Laravel app needs only S3, SQS, and DynamoDB, so prune the unused SDK services in a Composer step to stay small and cut cold starts.",[39,14500,14502],{"id":14501},"step-9-serve-static-assets-from-s3-not-lambda","Step 9: Serve static assets from S3, not Lambda",[11,14504,14505,14506,14509,14510,14513],{},"Lambda ",[1511,14507,14508],{},"can"," serve your CSS and JS, but every request wakes a function and burns runtime. For production, serve assets from S3 through ",[10490,14511,14512],{},"CloudFront"," (AWS's CDN). This is one-time infrastructure; the CI pipeline in Step 12 does the actual build and upload on every deploy.",[11,14515,14516],{},"Set it up once:",[11074,14518,14519,14525,14531],{},[11019,14520,14521,14522,81],{},"Create an S3 bucket for assets, for example ",[15,14523,14524],{},"acme-app-assets",[11019,14526,14527,14528,81],{},"Create a CloudFront distribution with that bucket as its origin, on a subdomain like ",[15,14529,14530],{},"assets.example.com",[11019,14532,14533],{},"Point Laravel at the CDN:",[83,14535,14537],{"className":12497,"code":14536,"language":12499,"meta":88,"style":88},"# .env\nASSET_URL=https://assets.example.com\n",[15,14538,14539,14543],{"__ignoreMap":88},[92,14540,14541],{"class":94,"line":95},[92,14542,12506],{},[92,14544,14545],{"class":94,"line":106},[92,14546,14547],{},"ASSET_URL=https://assets.example.com\n",[11,14549,14550,14551,14554,14555,14558],{},"Now ",[15,14552,14553],{},"asset()"," and Vite URLs resolve to CloudFront, so browsers never hit Lambda for a stylesheet. On each deploy, CI uploads the built files with ",[15,14556,14557],{},"aws s3 sync public/build s3://acme-app-assets/build"," (see Step 12).",[11813,14560,14561],{},[11,14562,14563,14566,14567,14569],{},[10490,14564,14565],{},"Images or PDFs return a 500?"," Add ",[15,14568,12405],{}," to the web function (already in the config above). API Gateway needs binary responses base64-encoded, and Bref only does that with this flag.",[11813,14571,14572],{},[11,14573,14574,14580],{},[10490,14575,14576,14577,81],{},"On updates, never use ",[15,14578,14579],{},"--delete"," Old browser tabs still request the previous hashed files during a rollout. Leave old assets in place and clean up later.",[39,14582,14584],{"id":14583},"step-10-add-a-custom-domain-cloudflare-acm","Step 10: Add a custom domain (Cloudflare + ACM)",[11,14586,14587,14588,14590,14591,81],{},"You want ",[15,14589,11003],{}," instead of the API Gateway hostname. You need admin access to the domain in Cloudflare, because you add DNS records there by hand. New to DNS records? See ",[23,14592,14594],{"href":14593},"/post/dns-explained-how-domain-name-system-works","how DNS works",[11074,14596,14597],{},[11019,14598,14599,14600,14603,14604,81],{},"In ",[10490,14601,14602],{},"ACM"," (AWS Certificate Manager, free TLS certificates), request a certificate for ",[15,14605,11003],{},[11813,14607,14608],{},[11,14609,14610,14613,14614,14616,14617,14620,14621,14623],{},[10490,14611,14612],{},"Region matters."," For a regional HTTP API, the certificate must be in the API's region (",[15,14615,11007],{},"), not ",[15,14618,14619],{},"us-east-1",". The ",[15,14622,14619],{}," rule is only for CloudFront.",[11074,14625,14626,14629],{"start":106},[11019,14627,14628],{},"ACM gives you a CNAME to prove ownership. Add it in Cloudflare and wait for the certificate to validate.",[11019,14630,14631,14632,14634,14635,14637,14638,14640],{},"Add the domain plugin and a ",[15,14633,4159],{}," block to ",[15,14636,11836],{},". The domain reads from the per-stage ",[15,14639,11964],{}," you set in Step 4:",[83,14642,14644],{"className":11840,"code":14643,"language":11842,"meta":88,"style":88},"# serverless.yml (add the plugin and a top-level custom: block)\nplugins:\n  - ./vendor/bref/bref\n  - serverless-domain-manager\n\ncustom:\n  customDomain:\n    domainName: ${param:domain} # example.com for prod, from params\n    certificateArn: arn:aws:acm:ap-south-1:123456789012:certificate/abcd-1234\n    endpointType: regional\n    apiType: http\n    createRoute53Record: false # you use Cloudflare, not Route 53\n",[15,14645,14646,14651,14657,14663,14670,14674,14680,14687,14700,14710,14720,14730],{"__ignoreMap":88},[92,14647,14648],{"class":94,"line":95},[92,14649,14650],{"class":134},"# serverless.yml (add the plugin and a top-level custom: block)\n",[92,14652,14653,14655],{"class":94,"line":106},[92,14654,12027],{"class":2145},[92,14656,4828],{"class":119},[92,14658,14659,14661],{"class":94,"line":113},[92,14660,12034],{"class":119},[92,14662,12037],{"class":171},[92,14664,14665,14667],{"class":94,"line":138},[92,14666,12034],{"class":119},[92,14668,14669],{"class":171},"serverless-domain-manager\n",[92,14671,14672],{"class":94,"line":143},[92,14673,110],{"emptyLinePlaceholder":109},[92,14675,14676,14678],{"class":94,"line":149},[92,14677,4159],{"class":2145},[92,14679,4828],{"class":119},[92,14681,14682,14685],{"class":94,"line":155},[92,14683,14684],{"class":2145},"  customDomain",[92,14686,4828],{"class":119},[92,14688,14689,14692,14694,14697],{"class":94,"line":161},[92,14690,14691],{"class":2145},"    domainName",[92,14693,5263],{"class":119},[92,14695,14696],{"class":171},"${param:domain}",[92,14698,14699],{"class":134}," # example.com for prod, from params\n",[92,14701,14702,14705,14707],{"class":94,"line":166},[92,14703,14704],{"class":2145},"    certificateArn",[92,14706,5263],{"class":119},[92,14708,14709],{"class":171},"arn:aws:acm:ap-south-1:123456789012:certificate/abcd-1234\n",[92,14711,14712,14715,14717],{"class":94,"line":187},[92,14713,14714],{"class":2145},"    endpointType",[92,14716,5263],{"class":119},[92,14718,14719],{"class":171},"regional\n",[92,14721,14722,14725,14727],{"class":94,"line":217},[92,14723,14724],{"class":2145},"    apiType",[92,14726,5263],{"class":119},[92,14728,14729],{"class":171},"http\n",[92,14731,14732,14735,14737,14739],{"class":94,"line":712},[92,14733,14734],{"class":2145},"    createRoute53Record",[92,14736,5263],{"class":119},[92,14738,2300],{"class":102},[92,14740,14741],{"class":134}," # you use Cloudflare, not Route 53\n",[11074,14743,14744,14754],{"start":138},[11019,14745,14746,14747,14750,14751,81],{},"Run ",[15,14748,14749],{},"serverless create_domain"," once. It prints a target like ",[15,14752,14753],{},"d-xxxx.execute-api.ap-south-1.amazonaws.com",[11019,14755,14756,14757,14759],{},"In Cloudflare, add a CNAME from ",[15,14758,11003],{}," to that target. If you proxy through Cloudflare, set SSL mode to Full.",[11813,14761,14762],{},[11,14763,14764,14767],{},[10490,14765,14766],{},"Migrating an existing app?"," Flip DNS last. Deploy and test on the API Gateway URL first, lower your Cloudflare record's TTL a day ahead, then switch the CNAME.",[39,14769,14771],{"id":14770},"step-11-add-php-extensions-and-raise-upload-limits-if-needed","Step 11: Add PHP extensions and raise upload limits (if needed)",[11,14773,14774,14775,14778,14779,14782,14783,14786],{},"Bref's base layer is lean. It has no ",[10490,14776,14777],{},"GD"," (image library) or ",[10490,14780,14781],{},"intl",", and small upload limits. Add extra layers and a ",[15,14784,14785],{},"php.ini"," only if your app needs them.",[83,14788,14790],{"className":11840,"code":14789,"language":11842,"meta":88,"style":88},"# serverless.yml (add to the web function)\nfunctions:\n  web:\n    layers:\n      - ${bref-extra:gd-php-83}\n      - ${bref-extra:intl-php-83}\n",[15,14791,14792,14797,14803,14809,14816,14823],{"__ignoreMap":88},[92,14793,14794],{"class":94,"line":95},[92,14795,14796],{"class":134},"# serverless.yml (add to the web function)\n",[92,14798,14799,14801],{"class":94,"line":106},[92,14800,5124],{"class":2145},[92,14802,4828],{"class":119},[92,14804,14805,14807],{"class":94,"line":113},[92,14806,12052],{"class":2145},[92,14808,4828],{"class":119},[92,14810,14811,14814],{"class":94,"line":138},[92,14812,14813],{"class":2145},"    layers",[92,14815,4828],{"class":119},[92,14817,14818,14820],{"class":94,"line":143},[92,14819,12123],{"class":119},[92,14821,14822],{"class":171},"${bref-extra:gd-php-83}\n",[92,14824,14825,14827],{"class":94,"line":149},[92,14826,12123],{"class":119},[92,14828,14829],{"class":171},"${bref-extra:intl-php-83}\n",[83,14831,14835],{"className":14832,"code":14833,"language":14834,"meta":88,"style":88},"language-ini shiki shiki-themes github-dark","; php/conf.d/php.ini  (its own file; Bref loads it automatically)\nupload_max_filesize = 20M\npost_max_size = 21M\nmemory_limit = 512M\n","ini",[15,14836,14837,14842,14847,14852],{"__ignoreMap":88},[92,14838,14839],{"class":94,"line":95},[92,14840,14841],{},"; php/conf.d/php.ini  (its own file; Bref loads it automatically)\n",[92,14843,14844],{"class":94,"line":106},[92,14845,14846],{},"upload_max_filesize = 20M\n",[92,14848,14849],{"class":94,"line":113},[92,14850,14851],{},"post_max_size = 21M\n",[92,14853,14854],{"class":94,"line":138},[92,14855,14856],{},"memory_limit = 512M\n",[39,14858,14860],{"id":14859},"step-12-automate-deploys-with-cicd","Step 12: Automate deploys with CI/CD",[11,14862,14863],{},"Deploy from a Linux runner, because PHP extension binaries are platform-specific. This GitHub Actions job builds, uploads assets, deploys, and runs migrations.",[83,14865,14867],{"className":11840,"code":14866,"language":11842,"meta":88,"style":88},"# .github/workflows/deploy.yml\nname: deploy\non:\n  push:\n    branches: [main]\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    permissions:\n      id-token: write # OIDC, no stored keys\n      contents: read\n    steps:\n      - uses: actions/checkout@v4\n      - uses: shivammathur/setup-php@v2\n        with: { php-version: '8.3' }\n      - run: composer install --no-dev --optimize-autoloader\n      - run: npm ci && npm run build\n      - run: aws s3 sync public/build s3://acme-app-assets/build # assets first, no --delete\n      - uses: aws-actions/configure-aws-credentials@v4\n        with:\n          role-to-assume: arn:aws:iam::123456789012:role/acme-deploy\n          aws-region: ap-south-1\n      - run: npm i -g osls\n      - run: serverless deploy --stage prod\n      - run: serverless bref:cli --stage prod --args=\"migrate --force\"\n",[15,14868,14869,14874,14883,14890,14897,14909,14916,14923,14933,14940,14953,14963,14970,14982,14993,15011,15023,15034,15047,15058,15064,15074,15083,15094,15104],{"__ignoreMap":88},[92,14870,14871],{"class":94,"line":95},[92,14872,14873],{"class":134},"# .github/workflows/deploy.yml\n",[92,14875,14876,14878,14880],{"class":94,"line":106},[92,14877,5271],{"class":2145},[92,14879,5263],{"class":119},[92,14881,14882],{"class":171},"deploy\n",[92,14884,14885,14888],{"class":94,"line":113},[92,14886,14887],{"class":102},"on",[92,14889,4828],{"class":119},[92,14891,14892,14895],{"class":94,"line":138},[92,14893,14894],{"class":2145},"  push",[92,14896,4828],{"class":119},[92,14898,14899,14902,14904,14907],{"class":94,"line":143},[92,14900,14901],{"class":2145},"    branches",[92,14903,13093],{"class":119},[92,14905,14906],{"class":171},"main",[92,14908,13109],{"class":119},[92,14910,14911,14914],{"class":94,"line":149},[92,14912,14913],{"class":2145},"jobs",[92,14915,4828],{"class":119},[92,14917,14918,14921],{"class":94,"line":155},[92,14919,14920],{"class":2145},"  deploy",[92,14922,4828],{"class":119},[92,14924,14925,14928,14930],{"class":94,"line":161},[92,14926,14927],{"class":2145},"    runs-on",[92,14929,5263],{"class":119},[92,14931,14932],{"class":171},"ubuntu-latest\n",[92,14934,14935,14938],{"class":94,"line":166},[92,14936,14937],{"class":2145},"    permissions",[92,14939,4828],{"class":119},[92,14941,14942,14945,14947,14950],{"class":94,"line":187},[92,14943,14944],{"class":2145},"      id-token",[92,14946,5263],{"class":119},[92,14948,14949],{"class":171},"write",[92,14951,14952],{"class":134}," # OIDC, no stored keys\n",[92,14954,14955,14958,14960],{"class":94,"line":217},[92,14956,14957],{"class":2145},"      contents",[92,14959,5263],{"class":119},[92,14961,14962],{"class":171},"read\n",[92,14964,14965,14968],{"class":94,"line":712},[92,14966,14967],{"class":2145},"    steps",[92,14969,4828],{"class":119},[92,14971,14972,14974,14977,14979],{"class":94,"line":730},[92,14973,12123],{"class":119},[92,14975,14976],{"class":2145},"uses",[92,14978,5263],{"class":119},[92,14980,14981],{"class":171},"actions/checkout@v4\n",[92,14983,14984,14986,14988,14990],{"class":94,"line":747},[92,14985,12123],{"class":119},[92,14987,14976],{"class":2145},[92,14989,5263],{"class":119},[92,14991,14992],{"class":171},"shivammathur/setup-php@v2\n",[92,14994,14995,14998,15001,15004,15006,15009],{"class":94,"line":763},[92,14996,14997],{"class":2145},"        with",[92,14999,15000],{"class":119},": { ",[92,15002,15003],{"class":2145},"php-version",[92,15005,5263],{"class":119},[92,15007,15008],{"class":171},"'8.3'",[92,15010,4506],{"class":119},[92,15012,15013,15015,15018,15020],{"class":94,"line":780},[92,15014,12123],{"class":119},[92,15016,15017],{"class":2145},"run",[92,15019,5263],{"class":119},[92,15021,15022],{"class":171},"composer install --no-dev --optimize-autoloader\n",[92,15024,15025,15027,15029,15031],{"class":94,"line":785},[92,15026,12123],{"class":119},[92,15028,15017],{"class":2145},[92,15030,5263],{"class":119},[92,15032,15033],{"class":171},"npm ci && npm run build\n",[92,15035,15036,15038,15040,15042,15044],{"class":94,"line":2585},[92,15037,12123],{"class":119},[92,15039,15017],{"class":2145},[92,15041,5263],{"class":119},[92,15043,14557],{"class":171},[92,15045,15046],{"class":134}," # assets first, no --delete\n",[92,15048,15049,15051,15053,15055],{"class":94,"line":2605},[92,15050,12123],{"class":119},[92,15052,14976],{"class":2145},[92,15054,5263],{"class":119},[92,15056,15057],{"class":171},"aws-actions/configure-aws-credentials@v4\n",[92,15059,15060,15062],{"class":94,"line":2634},[92,15061,14997],{"class":2145},[92,15063,4828],{"class":119},[92,15065,15066,15069,15071],{"class":94,"line":2651},[92,15067,15068],{"class":2145},"          role-to-assume",[92,15070,5263],{"class":119},[92,15072,15073],{"class":171},"arn:aws:iam::123456789012:role/acme-deploy\n",[92,15075,15076,15079,15081],{"class":94,"line":2671},[92,15077,15078],{"class":2145},"          aws-region",[92,15080,5263],{"class":119},[92,15082,11890],{"class":171},[92,15084,15085,15087,15089,15091],{"class":94,"line":2676},[92,15086,12123],{"class":119},[92,15088,15017],{"class":2145},[92,15090,5263],{"class":119},[92,15092,15093],{"class":171},"npm i -g osls\n",[92,15095,15096,15098,15100,15102],{"class":94,"line":2697},[92,15097,12123],{"class":119},[92,15099,15017],{"class":2145},[92,15101,5263],{"class":119},[92,15103,14392],{"class":171},[92,15105,15106,15108,15110,15112],{"class":94,"line":2726},[92,15107,12123],{"class":119},[92,15109,15017],{"class":2145},[92,15111,5263],{"class":119},[92,15113,15114],{"class":171},"serverless bref:cli --stage prod --args=\"migrate --force\"\n",[11,15116,15117,15118,15121],{},"Because the app's secrets live in SSM (Step 6), the deploy resolves them with the OIDC role at deploy time. No application secrets are stored in GitHub; only the deploy role is trusted. The ",[15,15119,15120],{},"migrate --force"," step runs on Lambda, where the database env variables are already in place from the deploy.",[11,15123,15124],{},"Run a command or read logs on demand:",[83,15126,15128],{"className":11136,"code":15127,"language":11138,"meta":88,"style":88},"serverless bref:cli --stage prod --args=\"acme:heartbeat\"\nserverless logs -f web --stage prod --tail\n",[15,15129,15130,15148],{"__ignoreMap":88},[92,15131,15132,15134,15137,15139,15142,15145],{"class":94,"line":95},[92,15133,11827],{"class":5161},[92,15135,15136],{"class":171}," bref:cli",[92,15138,14404],{"class":102},[92,15140,15141],{"class":171}," prod",[92,15143,15144],{"class":102}," --args=",[92,15146,15147],{"class":171},"\"acme:heartbeat\"\n",[92,15149,15150,15152,15155,15158,15161,15163,15165],{"class":94,"line":106},[92,15151,11827],{"class":5161},[92,15153,15154],{"class":171}," logs",[92,15156,15157],{"class":102}," -f",[92,15159,15160],{"class":171}," web",[92,15162,14404],{"class":102},[92,15164,15141],{"class":171},[92,15166,15167],{"class":102}," --tail\n",[11813,15169,15170],{},[11,15171,15172,15175,15176,15179,15180,15182,15183,15186,15187,81],{},[10490,15173,15174],{},"Single-quote secrets in the shell."," A password like ",[15,15177,15178],{},"p@ss$word"," has a ",[15,15181,251],{},"; double quotes make the shell expand ",[15,15184,15185],{},"$word"," and truncate it. Write ",[15,15188,15189],{},"DB_PASSWORD='${{ secrets.DB_PASSWORD }}'",[11813,15191,15192],{},[11,15193,15194,1644,15197,15200,15201,15204],{},[10490,15195,15196],{},"Prefer OIDC over stored keys.",[15,15198,15199],{},"configure-aws-credentials"," with ",[15,15202,15203],{},"role-to-assume"," gets short-lived credentials, so nothing leaks from the repo.",[39,15206,15208],{"id":15207},"production-checklist","Production checklist",[11016,15210,15211,15221,15227,15237,15243,15249,15263],{},[11019,15212,15213,15216,15217,15220],{},[10490,15214,15215],{},"Cold starts:"," a ",[1511,15218,15219],{},"cold start"," is the delay when Lambda boots a fresh instance. For latency-sensitive traffic, add provisioned concurrency (pre-warmed instances).",[11019,15222,15223,15226],{},[10490,15224,15225],{},"Memory:"," more memory means more CPU. Bumping the web function to 1024 MB often lowers cost by finishing faster.",[11019,15228,15229,15232,15233,15236],{},[10490,15230,15231],{},"Database connections:"," Lambda scales wide and each instance opens a connection. Cap the worker (",[15,15234,15235],{},"maximumConcurrency",") and consider RDS Proxy.",[11019,15238,15239,15242],{},[10490,15240,15241],{},"Log retention:"," set a retention period on CloudWatch log groups; the default is forever.",[11019,15244,15245,15248],{},[10490,15246,15247],{},"Dead-letter alarm:"," alert on the dead-letter queue depth so failed jobs do not go unnoticed.",[11019,15250,15251,15254,15255,15258,15259,15262],{},[10490,15252,15253],{},"VPC only if the database is private."," A public managed database needs no ",[10490,15256,15257],{},"VPC"," (a private AWS network). A private RDS instance needs one, and then Lambda loses internet, so it needs a ",[10490,15260,15261],{},"NAT"," gateway or VPC endpoints to reach S3, SQS, and DynamoDB. A VPC also adds cold-start latency and cost.",[11019,15264,15265,15268],{},[10490,15266,15267],{},"Managed-DB quirks:"," if a database rejects a connection init command that another accepts, apply it conditionally (keyed on an env flag), not globally.",[11,15270,15271],{},"On cost: Lambda, API Gateway, SQS, DynamoDB, and S3 all scale to near-zero when idle. The two things that do not are provisioned concurrency and a NAT gateway, both billed around the clock.",[39,15273,15275],{"id":15274},"bref-and-laravel-on-lambda-faq","Bref and Laravel on Lambda: FAQ",[11,15277,15278,15281],{},[10490,15279,15280],{},"Can you run Laravel on AWS Lambda?","\nYes. Laravel is not serverless by default, but Bref packages PHP as Lambda layers and runs your app almost unchanged, once you move sessions, cache, files, and the queue to managed services. This guide walks through the whole process.",[11,15283,15284,15287],{},[10490,15285,15286],{},"Is Bref free?","\nYes. Bref is open-source. You pay only AWS for what you use. Laravel Vapor adds a subscription on top.",[11,15289,15290,15293],{},[10490,15291,15292],{},"Does Laravel Horizon work on AWS Lambda?","\nNo. Horizon needs a long-running process. Use the SQS queue driver with Bref's worker; SQS gives you retries and a dead-letter queue.",[11,15295,15296,15299],{},[10490,15297,15298],{},"How much does it cost to run Laravel on Lambda?","\nFor low or spiky traffic, very little. The AWS free tier covers about 1 million requests and 400,000 GB-seconds a month. Avoid a VPC unless a private database forces one.",[11,15301,15302,15305],{},[10490,15303,15304],{},"Can I use MySQL or RDS?","\nYes. A public managed database needs no VPC. A private RDS instance needs a VPC plus a NAT gateway or VPC endpoints.",[11,15307,15308,15311,15312,81],{},[10490,15309,15310],{},"Which PHP versions does Bref support?","\nCurrent versions, roughly 8.1 to 8.4. Match the runtime to your app, for example ",[15,15313,15314],{},"php-83-fpm",[39,15316,15318],{"id":15317},"recap","Recap",[11,15320,15321],{},"You deployed a Laravel app to AWS Lambda with Bref, moved every stateful driver to a managed service (DynamoDB, SQS, S3, CloudWatch), replaced cron with EventBridge, added a custom HTTPS domain through Cloudflare and ACM, and automated it with CI. The recurring theme: a read-only disk, no long processes, and a 29-second limit, so state lives in managed services and long work goes to the queue.",[39,15323,15325],{"id":15324},"what-to-try-next","What to try next",[11016,15327,15328,15331,15334,15343],{},[11019,15329,15330],{},"Add provisioned concurrency to the web function and measure the cold-start drop.",[11019,15332,15333],{},"Alarm on the dead-letter queue, then force a job to fail and watch it fire.",[11019,15335,15336,15337,15200,15340,81],{},"Deploy a staging copy on ",[15,15338,15339],{},"staging.example.com",[15,15341,15342],{},"serverless deploy --stage staging",[11019,15344,15345],{},"Move a slow endpoint onto the queue so it never risks the 29-second limit.",[11,15347,15348,15349,10192,15352,81],{},"To sharpen the Laravel and PHP fundamentals behind this, see the ",[23,15350,15351],{"href":25},"Top 111 Laravel interview questions",[23,15353,15355],{"href":15354},"/post/php-syntax-recap","PHP syntax recap",[10887,15357,15358],{},"html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .s4JwU, html code.shiki .s4JwU{--shiki-default:#85E89D}",{"title":88,"searchDepth":106,"depth":106,"links":15360},[15361,15362,15363,15366,15367,15368,15369,15370,15371,15379,15380,15381,15382,15383,15384,15385,15386,15387,15388,15389],{"id":11010,"depth":106,"text":11011},{"id":11042,"depth":106,"text":11043},{"id":11060,"depth":106,"text":11061,"children":15364},[15365],{"id":11109,"depth":113,"text":11110},{"id":11116,"depth":106,"text":11117},{"id":11129,"depth":106,"text":11130},{"id":11178,"depth":106,"text":11179},{"id":11760,"depth":106,"text":11761},{"id":11830,"depth":106,"text":11831},{"id":12480,"depth":106,"text":12481,"children":15372},[15373,15374,15375,15376,15377,15378],{"id":12487,"depth":113,"text":12488},{"id":12692,"depth":113,"text":12693},{"id":12864,"depth":113,"text":12865},{"id":13004,"depth":113,"text":13005},{"id":13025,"depth":113,"text":13026},{"id":13169,"depth":113,"text":13170},{"id":13898,"depth":106,"text":13899},{"id":14156,"depth":106,"text":14157},{"id":14388,"depth":106,"text":14389},{"id":14501,"depth":106,"text":14502},{"id":14583,"depth":106,"text":14584},{"id":14770,"depth":106,"text":14771},{"id":14859,"depth":106,"text":14860},{"id":15207,"depth":106,"text":15208},{"id":15274,"depth":106,"text":15275},{"id":15317,"depth":106,"text":15318},{"id":15324,"depth":106,"text":15325},"2026-09-03","Deploy Laravel serverless on AWS Lambda with Bref. A step-by-step guide to Laravel serverless deployment: SQS, DynamoDB, S3, a custom domain, and CI/CD.","deploy-laravel-on-aws-lambda-with-bref.png",{},"/backend/deploy-laravel-on-aws-lambda-with-bref",{"title":10984,"description":15391},"Backend/10.deploy-laravel-on-aws-lambda-with-bref",[15398,11071,10992,15399,10975,10977,15400],"Laravel","Serverless","DevOps","9Sv2d5e2eM6Zcx_MT88_turE0msaaZtp-dkQuRKoYKA",{"id":4,"title":5,"author":6,"body":15403,"date":10964,"description":10965,"draft":10966,"extension":10967,"guide":10968,"image":10969,"meta":24208,"navigation":109,"path":10971,"seo":24209,"stem":10973,"tags":24210,"__hash__":10980},{"type":8,"value":15404,"toc":24135},[15405,15409,15417,15419,15439,15537,15541,15543,15545,15551,15635,15637,15667,15747,15749,15771,15975,15977,15995,16095,16097,16117,16237,16243,16245,16247,16269,16387,16389,16411,16503,16505,16529,16609,16611,16631,16725,16727,16751,16853,16869,16871,16873,16887,17049,17051,17057,17109,17111,17119,17519,17521,17525,17581,17595,17597,17599,17611,17765,17769,17771,17785,17929,17931,17949,18141,18143,18153,18557,18559,18567,18673,18825,18827,18837,18967,18975,18977,18979,19005,19215,19217,19227,19407,19415,19417,19419,19431,19577,19579,19587,19709,19711,19719,19803,19805,19817,19995,19997,20007,20067,20069,20075,20205,20211,20213,20217,20225,20399,20401,20413,20519,20521,20531,20709,20711,20715,20817,20819,20831,20971,20973,20981,21135,21137,21141,21337,21339,21345,21541,21547,21549,21557,21767,21769,21785,21999,22001,22023,22243,22245,22257,22365,22367,22383,22475,22477,22479,22489,22613,22615,22627,22687,22689,22723,22727,22729,22741,22883,22893,22895,22897,22911,22993,22995,23009,23207,23209,23229,23323,23325,23335,23443,23445,23465,23605,23607,23623,23865,23867,23869,23871,23891,23929,23947,23953,23957,23971,23987,24011,24027,24047,24057,24071,24103,24125,24133],[11,15406,13,15407,18],{},[15,15408,17],{},[11,15410,21,15411,27,15413,32,15415,37],{},[23,15412,26],{"href":25},[23,15414,31],{"href":30},[23,15416,36],{"href":35},[39,15418,42],{"id":41},[11,15420,45,15421,49,15423,53,15425,57,15427,61,15429,65,15431,69,15433,73,15435,77,15437,81],{},[15,15422,48],{},[15,15424,52],{},[15,15426,56],{},[15,15428,60],{},[15,15430,64],{},[15,15432,68],{},[15,15434,72],{},[15,15436,76],{},[15,15438,80],{},[83,15440,15441],{"className":85,"code":86,"language":87,"meta":88,"style":88},[15,15442,15443,15449,15453,15469,15473,15477,15481,15485,15489,15503,15525],{"__ignoreMap":88},[92,15444,15445,15447],{"class":94,"line":95},[92,15446,99],{"class":98},[92,15448,103],{"class":102},[92,15450,15451],{"class":94,"line":106},[92,15452,110],{"emptyLinePlaceholder":109},[92,15454,15455,15457,15459,15461,15463,15465,15467],{"class":94,"line":113},[92,15456,116],{"class":98},[92,15458,120],{"class":119},[92,15460,123],{"class":102},[92,15462,126],{"class":98},[92,15464,68],{"class":102},[92,15466,131],{"class":119},[92,15468,135],{"class":134},[92,15470,15471],{"class":94,"line":138},[92,15472,110],{"emptyLinePlaceholder":109},[92,15474,15475],{"class":94,"line":143},[92,15476,146],{"class":134},[92,15478,15479],{"class":94,"line":149},[92,15480,152],{"class":134},[92,15482,15483],{"class":94,"line":155},[92,15484,158],{"class":134},[92,15486,15487],{"class":94,"line":161},[92,15488,110],{"emptyLinePlaceholder":109},[92,15490,15491,15493,15495,15497,15499,15501],{"class":94,"line":166},[92,15492,60],{"class":102},[92,15494,172],{"class":171},[92,15496,175],{"class":102},[92,15498,178],{"class":171},[92,15500,181],{"class":119},[92,15502,184],{"class":134},[92,15504,15505,15507,15509,15511,15513,15515,15517,15519,15521,15523],{"class":94,"line":187},[92,15506,60],{"class":102},[92,15508,192],{"class":171},[92,15510,195],{"class":119},[92,15512,198],{"class":171},[92,15514,195],{"class":119},[92,15516,203],{"class":171},[92,15518,195],{"class":119},[92,15520,208],{"class":102},[92,15522,211],{"class":119},[92,15524,214],{"class":134},[92,15526,15527,15529,15531,15533,15535],{"class":94,"line":217},[92,15528,64],{"class":102},[92,15530,222],{"class":171},[92,15532,175],{"class":102},[92,15534,178],{"class":171},[92,15536,229],{"class":119},[11,15538,232,15539,81],{},[23,15540,236],{"href":235},[39,15542,240],{"id":239},[242,15544,245],{"id":244},[11,15546,248,15547,252,15549,256],{},[15,15548,251],{},[15,15550,255],{},[83,15552,15553],{"className":85,"code":259,"language":87,"meta":88,"style":88},[15,15554,15555,15565,15575,15585,15597,15601,15617],{"__ignoreMap":88},[92,15556,15557,15559,15561,15563],{"class":94,"line":95},[92,15558,266],{"class":119},[92,15560,126],{"class":98},[92,15562,271],{"class":171},[92,15564,229],{"class":119},[92,15566,15567,15569,15571,15573],{"class":94,"line":106},[92,15568,278],{"class":119},[92,15570,126],{"class":98},[92,15572,283],{"class":102},[92,15574,229],{"class":119},[92,15576,15577,15579,15581,15583],{"class":94,"line":113},[92,15578,290],{"class":119},[92,15580,126],{"class":98},[92,15582,295],{"class":102},[92,15584,229],{"class":119},[92,15586,15587,15589,15591,15593,15595],{"class":94,"line":138},[92,15588,278],{"class":119},[92,15590,126],{"class":98},[92,15592,306],{"class":171},[92,15594,309],{"class":119},[92,15596,312],{"class":134},[92,15598,15599],{"class":94,"line":143},[92,15600,110],{"emptyLinePlaceholder":109},[92,15602,15603,15605,15607,15609,15611,15613,15615],{"class":94,"line":149},[92,15604,321],{"class":119},[92,15606,126],{"class":98},[92,15608,326],{"class":119},[92,15610,126],{"class":98},[92,15612,331],{"class":102},[92,15614,334],{"class":119},[92,15616,337],{"class":134},[92,15618,15619,15621,15623,15625,15627,15629,15631,15633],{"class":94,"line":155},[92,15620,342],{"class":119},[92,15622,126],{"class":98},[92,15624,347],{"class":119},[92,15626,68],{"class":102},[92,15628,195],{"class":119},[92,15630,354],{"class":102},[92,15632,357],{"class":119},[92,15634,360],{"class":134},[242,15636,364],{"id":363},[11,15638,367,15639,195,15641,195,15643,195,15645,380,15647,195,15649,387,15651,195,15653,394,15655,398,15657,401,15659,404,15661,408,15663,412,15665,415],{},[15,15640,370],{},[15,15642,373],{},[15,15644,376],{},[15,15646,379],{},[15,15648,383],{},[15,15650,386],{},[15,15652,390],{},[15,15654,393],{},[15,15656,397],{},[15,15658,370],{},[15,15660,373],{},[15,15662,407],{},[15,15664,411],{},[15,15666,407],{},[83,15668,15669],{"className":85,"code":418,"language":87,"meta":88,"style":88},[15,15670,15671,15683,15695,15707,15719,15735],{"__ignoreMap":88},[92,15672,15673,15675,15677,15679,15681],{"class":94,"line":95},[92,15674,425],{"class":102},[92,15676,120],{"class":119},[92,15678,430],{"class":102},[92,15680,433],{"class":119},[92,15682,436],{"class":134},[92,15684,15685,15687,15689,15691,15693],{"class":94,"line":106},[92,15686,425],{"class":102},[92,15688,120],{"class":119},[92,15690,445],{"class":102},[92,15692,448],{"class":119},[92,15694,451],{"class":134},[92,15696,15697,15699,15701,15703,15705],{"class":94,"line":113},[92,15698,425],{"class":102},[92,15700,120],{"class":119},[92,15702,460],{"class":171},[92,15704,448],{"class":119},[92,15706,465],{"class":134},[92,15708,15709,15711,15713,15715,15717],{"class":94,"line":138},[92,15710,425],{"class":102},[92,15712,120],{"class":119},[92,15714,474],{"class":102},[92,15716,448],{"class":119},[92,15718,479],{"class":134},[92,15720,15721,15723,15725,15727,15729,15731,15733],{"class":94,"line":143},[92,15722,425],{"class":102},[92,15724,486],{"class":119},[92,15726,68],{"class":102},[92,15728,195],{"class":119},[92,15730,354],{"class":102},[92,15732,495],{"class":119},[92,15734,498],{"class":134},[92,15736,15737,15739,15741,15743,15745],{"class":94,"line":149},[92,15738,425],{"class":102},[92,15740,120],{"class":119},[92,15742,390],{"class":102},[92,15744,448],{"class":119},[92,15746,511],{"class":134},[242,15748,515],{"id":514},[11,15750,518,15751,521,15753,525,15755,529,15757,529,15759,529,15761,539,15763,543,15765,547,15767,551,15769,81],{},[15,15752,407],{},[15,15754,524],{},[15,15756,528],{},[15,15758,532],{},[15,15760,535],{},[15,15762,538],{},[15,15764,542],{},[15,15766,546],{},[15,15768,550],{},[15,15770,554],{},[83,15772,15773],{"className":85,"code":557,"language":87,"meta":88,"style":88},[15,15774,15775,15787,15799,15811,15823,15835,15843,15855,15867,15871,15885,15899,15913,15927,15941,15955,15959],{"__ignoreMap":88},[92,15776,15777,15779,15781,15783,15785],{"class":94,"line":95},[92,15778,564],{"class":102},[92,15780,120],{"class":119},[92,15782,430],{"class":102},[92,15784,571],{"class":119},[92,15786,574],{"class":134},[92,15788,15789,15791,15793,15795,15797],{"class":94,"line":106},[92,15790,579],{"class":102},[92,15792,120],{"class":119},[92,15794,445],{"class":102},[92,15796,448],{"class":119},[92,15798,574],{"class":134},[92,15800,15801,15803,15805,15807,15809],{"class":94,"line":113},[92,15802,592],{"class":102},[92,15804,120],{"class":119},[92,15806,460],{"class":171},[92,15808,599],{"class":119},[92,15810,574],{"class":134},[92,15812,15813,15815,15817,15819,15821],{"class":94,"line":138},[92,15814,606],{"class":102},[92,15816,120],{"class":119},[92,15818,474],{"class":102},[92,15820,613],{"class":119},[92,15822,574],{"class":134},[92,15824,15825,15827,15829,15831,15833],{"class":94,"line":143},[92,15826,620],{"class":102},[92,15828,486],{"class":119},[92,15830,68],{"class":102},[92,15832,627],{"class":119},[92,15834,574],{"class":134},[92,15836,15837,15839,15841],{"class":94,"line":149},[92,15838,634],{"class":102},[92,15840,637],{"class":119},[92,15842,640],{"class":134},[92,15844,15845,15847,15849,15851,15853],{"class":94,"line":155},[92,15846,645],{"class":102},[92,15848,120],{"class":119},[92,15850,650],{"class":171},[92,15852,653],{"class":119},[92,15854,656],{"class":134},[92,15856,15857,15859,15861,15863,15865],{"class":94,"line":161},[92,15858,661],{"class":102},[92,15860,120],{"class":119},[92,15862,666],{"class":171},[92,15864,653],{"class":119},[92,15866,574],{"class":134},[92,15868,15869],{"class":94,"line":166},[92,15870,110],{"emptyLinePlaceholder":109},[92,15872,15873,15875,15877,15879,15881,15883],{"class":94,"line":187},[92,15874,120],{"class":119},[92,15876,370],{"class":98},[92,15878,683],{"class":119},[92,15880,686],{"class":171},[92,15882,689],{"class":119},[92,15884,692],{"class":134},[92,15886,15887,15889,15891,15893,15895,15897],{"class":94,"line":217},[92,15888,120],{"class":119},[92,15890,370],{"class":98},[92,15892,683],{"class":119},[92,15894,703],{"class":171},[92,15896,706],{"class":119},[92,15898,709],{"class":134},[92,15900,15901,15903,15905,15907,15909,15911],{"class":94,"line":712},[92,15902,120],{"class":119},[92,15904,373],{"class":98},[92,15906,683],{"class":119},[92,15908,721],{"class":171},[92,15910,724],{"class":119},[92,15912,727],{"class":134},[92,15914,15915,15917,15919,15921,15923,15925],{"class":94,"line":730},[92,15916,120],{"class":119},[92,15918,379],{"class":98},[92,15920,683],{"class":119},[92,15922,739],{"class":171},[92,15924,181],{"class":119},[92,15926,744],{"class":134},[92,15928,15929,15931,15933,15935,15937,15939],{"class":94,"line":747},[92,15930,120],{"class":119},[92,15932,376],{"class":98},[92,15934,683],{"class":119},[92,15936,474],{"class":102},[92,15938,689],{"class":119},[92,15940,760],{"class":134},[92,15942,15943,15945,15947,15949,15951,15953],{"class":94,"line":763},[92,15944,120],{"class":119},[92,15946,383],{"class":98},[92,15948,683],{"class":119},[92,15950,772],{"class":171},[92,15952,706],{"class":119},[92,15954,777],{"class":134},[92,15956,15957],{"class":94,"line":780},[92,15958,110],{"emptyLinePlaceholder":109},[92,15960,15961,15963,15965,15967,15969,15971,15973],{"class":94,"line":785},[92,15962,528],{"class":102},[92,15964,120],{"class":119},[92,15966,792],{"class":171},[92,15968,195],{"class":119},[92,15970,797],{"class":102},[92,15972,800],{"class":119},[92,15974,803],{"class":134},[242,15976,807],{"id":806},[11,15978,810,15979,813,15981,817,15983,821,15985,195,15987,394,15989,830,15991,834,15993,838],{},[15,15980,251],{},[15,15982,816],{},[15,15984,820],{},[15,15986,824],{},[15,15988,208],{},[15,15990,829],{},[15,15992,833],{},[15,15994,837],{},[83,15996,15997],{"className":85,"code":841,"language":87,"meta":88,"style":88},[15,15998,15999,16013,16029,16051,16055,16065,16075,16085],{"__ignoreMap":88},[92,16000,16001,16003,16005,16007,16009,16011],{"class":94,"line":95},[92,16002,816],{"class":98},[92,16004,850],{"class":102},[92,16006,853],{"class":98},[92,16008,856],{"class":102},[92,16010,181],{"class":119},[92,16012,861],{"class":134},[92,16014,16015,16017,16019,16021,16023,16025,16027],{"class":94,"line":106},[92,16016,866],{"class":102},[92,16018,120],{"class":119},[92,16020,871],{"class":171},[92,16022,195],{"class":119},[92,16024,876],{"class":171},[92,16026,448],{"class":119},[92,16028,881],{"class":134},[92,16030,16031,16033,16035,16037,16039,16041,16043,16045,16047,16049],{"class":94,"line":113},[92,16032,60],{"class":102},[92,16034,888],{"class":102},[92,16036,120],{"class":119},[92,16038,871],{"class":171},[92,16040,683],{"class":119},[92,16042,897],{"class":98},[92,16044,900],{"class":171},[92,16046,903],{"class":98},[92,16048,906],{"class":171},[92,16050,229],{"class":119},[92,16052,16053],{"class":94,"line":138},[92,16054,110],{"emptyLinePlaceholder":109},[92,16056,16057,16059,16061,16063],{"class":94,"line":143},[92,16058,60],{"class":102},[92,16060,919],{"class":102},[92,16062,309],{"class":119},[92,16064,924],{"class":134},[92,16066,16067,16069,16071,16073],{"class":94,"line":149},[92,16068,60],{"class":102},[92,16070,931],{"class":102},[92,16072,689],{"class":119},[92,16074,936],{"class":134},[92,16076,16077,16079,16081,16083],{"class":94,"line":155},[92,16078,60],{"class":102},[92,16080,943],{"class":102},[92,16082,946],{"class":119},[92,16084,949],{"class":134},[92,16086,16087,16089,16091,16093],{"class":94,"line":161},[92,16088,60],{"class":102},[92,16090,956],{"class":102},[92,16092,689],{"class":119},[92,16094,961],{"class":134},[242,16096,965],{"id":964},[11,16098,968,16099,972,16101,975,16103,979,16105,983,16107,987,16109,990,16111,993,16113,997,16115,81],{},[15,16100,971],{},[15,16102,390],{},[15,16104,978],{},[15,16106,982],{},[15,16108,986],{},[15,16110,474],{},[15,16112,978],{},[15,16114,996],{},[15,16116,390],{},[83,16118,16119],{"className":85,"code":1002,"language":87,"meta":88,"style":88},[15,16120,16121,16145,16149,16161,16173,16185,16197,16209,16221,16225],{"__ignoreMap":88},[92,16122,16123,16125,16127,16129,16131,16133,16135,16137,16139,16141,16143],{"class":94,"line":95},[92,16124,1009],{"class":119},[92,16126,126],{"class":98},[92,16128,347],{"class":119},[92,16130,1016],{"class":171},[92,16132,1019],{"class":98},[92,16134,271],{"class":171},[92,16136,195],{"class":119},[92,16138,1026],{"class":171},[92,16140,1019],{"class":98},[92,16142,1031],{"class":102},[92,16144,1034],{"class":119},[92,16146,16147],{"class":94,"line":106},[92,16148,110],{"emptyLinePlaceholder":109},[92,16150,16151,16153,16155,16157,16159],{"class":94,"line":113},[92,16152,1043],{"class":102},[92,16154,1046],{"class":119},[92,16156,1016],{"class":171},[92,16158,1051],{"class":119},[92,16160,574],{"class":134},[92,16162,16163,16165,16167,16169,16171],{"class":94,"line":138},[92,16164,1043],{"class":102},[92,16166,1046],{"class":119},[92,16168,1026],{"class":171},[92,16170,1064],{"class":119},[92,16172,1067],{"class":134},[92,16174,16175,16177,16179,16181,16183],{"class":94,"line":143},[92,16176,1043],{"class":102},[92,16178,1046],{"class":119},[92,16180,1076],{"class":171},[92,16182,1079],{"class":119},[92,16184,1082],{"class":134},[92,16186,16187,16189,16191,16193,16195],{"class":94,"line":149},[92,16188,1087],{"class":102},[92,16190,120],{"class":119},[92,16192,1026],{"class":171},[92,16194,1094],{"class":119},[92,16196,1097],{"class":134},[92,16198,16199,16201,16203,16205,16207],{"class":94,"line":155},[92,16200,1102],{"class":102},[92,16202,1046],{"class":119},[92,16204,1016],{"class":171},[92,16206,1051],{"class":119},[92,16208,1082],{"class":134},[92,16210,16211,16213,16215,16217,16219],{"class":94,"line":161},[92,16212,1102],{"class":102},[92,16214,1046],{"class":119},[92,16216,1076],{"class":171},[92,16218,1079],{"class":119},[92,16220,574],{"class":134},[92,16222,16223],{"class":94,"line":166},[92,16224,110],{"emptyLinePlaceholder":109},[92,16226,16227,16229,16231,16233,16235],{"class":94,"line":187},[92,16228,1131],{"class":102},[92,16230,1046],{"class":119},[92,16232,1016],{"class":171},[92,16234,1051],{"class":119},[92,16236,1140],{"class":134},[11,16238,1143,16239,1147,16241,1151],{},[15,16240,1146],{},[15,16242,1150],{},[39,16244,1155],{"id":1154},[242,16246,1159],{"id":1158},[11,16248,1162,16249,1166,16251,1169,16253,1172,16255,834,16257,1179,16259,195,16261,195,16263,1189,16265,1192,16267,81],{},[15,16250,1165],{},[15,16252,529],{},[15,16254,373],{},[15,16256,1175],{},[15,16258,1178],{},[15,16260,1182],{},[15,16262,1185],{},[15,16264,1188],{},[15,16266,81],{},[15,16268,1195],{},[83,16270,16271],{"className":85,"code":1198,"language":87,"meta":88,"style":88},[15,16272,16273,16285,16297,16309,16325,16337,16349,16353,16363,16375],{"__ignoreMap":88},[92,16274,16275,16277,16279,16281,16283],{"class":94,"line":95},[92,16276,1205],{"class":102},[92,16278,1208],{"class":98},[92,16280,856],{"class":102},[92,16282,946],{"class":119},[92,16284,1215],{"class":134},[92,16286,16287,16289,16291,16293,16295],{"class":94,"line":106},[92,16288,1205],{"class":102},[92,16290,1222],{"class":98},[92,16292,1225],{"class":102},[92,16294,946],{"class":119},[92,16296,1230],{"class":134},[92,16298,16299,16301,16303,16305,16307],{"class":94,"line":113},[92,16300,1235],{"class":102},[92,16302,1222],{"class":98},[92,16304,1225],{"class":102},[92,16306,946],{"class":119},[92,16308,1244],{"class":134},[92,16310,16311,16313,16315,16317,16319,16321,16323],{"class":94,"line":138},[92,16312,1249],{"class":102},[92,16314,120],{"class":119},[92,16316,1205],{"class":102},[92,16318,195],{"class":119},[92,16320,354],{"class":102},[92,16322,653],{"class":119},[92,16324,1262],{"class":134},[92,16326,16327,16329,16331,16333,16335],{"class":94,"line":143},[92,16328,1205],{"class":102},[92,16330,1269],{"class":98},[92,16332,856],{"class":102},[92,16334,946],{"class":119},[92,16336,1276],{"class":134},[92,16338,16339,16341,16343,16345,16347],{"class":94,"line":149},[92,16340,354],{"class":102},[92,16342,1283],{"class":98},[92,16344,1286],{"class":102},[92,16346,211],{"class":119},[92,16348,1291],{"class":134},[92,16350,16351],{"class":94,"line":155},[92,16352,110],{"emptyLinePlaceholder":109},[92,16354,16355,16357,16359,16361],{"class":94,"line":161},[92,16356,1300],{"class":119},[92,16358,126],{"class":98},[92,16360,1286],{"class":102},[92,16362,229],{"class":119},[92,16364,16365,16367,16369,16371,16373],{"class":94,"line":166},[92,16366,1300],{"class":119},[92,16368,1182],{"class":98},[92,16370,1315],{"class":102},[92,16372,309],{"class":119},[92,16374,1320],{"class":134},[92,16376,16377,16379,16381,16383,16385],{"class":94,"line":187},[92,16378,1300],{"class":119},[92,16380,1195],{"class":98},[92,16382,1329],{"class":171},[92,16384,975],{"class":119},[92,16386,1334],{"class":134},[242,16388,1338],{"id":1337},[11,16390,1341,16391,1345,16393,1349,16395,1353,16397,1357,16399,1361,16401,1365,16403,1369,16405,195,16407,1375,16409,1378],{},[15,16392,1344],{},[15,16394,1348],{},[15,16396,1352],{},[15,16398,1356],{},[15,16400,1360],{},[15,16402,1364],{},[15,16404,1368],{},[15,16406,1372],{},[15,16408,554],{},[15,16410,68],{},[83,16412,16413],{"className":85,"code":1381,"language":87,"meta":88,"style":88},[15,16414,16415,16427,16439,16451,16463,16467,16479,16491],{"__ignoreMap":88},[92,16416,16417,16419,16421,16423,16425],{"class":94,"line":95},[92,16418,68],{"class":102},[92,16420,1390],{"class":98},[92,16422,1393],{"class":171},[92,16424,211],{"class":119},[92,16426,1398],{"class":134},[92,16428,16429,16431,16433,16435,16437],{"class":94,"line":106},[92,16430,68],{"class":102},[92,16432,1405],{"class":98},[92,16434,1393],{"class":171},[92,16436,309],{"class":119},[92,16438,1412],{"class":134},[92,16440,16441,16443,16445,16447,16449],{"class":94,"line":113},[92,16442,68],{"class":102},[92,16444,1419],{"class":98},[92,16446,1225],{"class":102},[92,16448,946],{"class":119},[92,16450,574],{"class":134},[92,16452,16453,16455,16457,16459,16461],{"class":94,"line":138},[92,16454,68],{"class":102},[92,16456,1432],{"class":98},[92,16458,1393],{"class":171},[92,16460,309],{"class":119},[92,16462,1439],{"class":134},[92,16464,16465],{"class":94,"line":143},[92,16466,110],{"emptyLinePlaceholder":109},[92,16468,16469,16471,16473,16475,16477],{"class":94,"line":149},[92,16470,1448],{"class":102},[92,16472,1451],{"class":98},[92,16474,1315],{"class":102},[92,16476,724],{"class":119},[92,16478,1458],{"class":134},[92,16480,16481,16483,16485,16487,16489],{"class":94,"line":155},[92,16482,1463],{"class":102},[92,16484,1451],{"class":98},[92,16486,1315],{"class":102},[92,16488,724],{"class":119},[92,16490,1472],{"class":134},[92,16492,16493,16495,16497,16499,16501],{"class":94,"line":161},[92,16494,1205],{"class":102},[92,16496,1451],{"class":98},[92,16498,1315],{"class":102},[92,16500,724],{"class":119},[92,16502,1485],{"class":134},[242,16504,1489],{"id":1488},[11,16506,1492,16507,195,16509,394,16511,1502,16513,834,16515,1509,16517,1514,16519,1517,16521,1521,16523,1524,16525,1528,16527,1531],{},[15,16508,1495],{},[15,16510,1498],{},[15,16512,1501],{},[15,16514,1505],{},[15,16516,1508],{},[1511,16518,1513],{},[15,16520,126],{},[15,16522,1520],{},[15,16524,474],{},[15,16526,1527],{},[15,16528,1505],{},[83,16530,16531],{"className":85,"code":1534,"language":87,"meta":88,"style":88},[15,16532,16533,16545,16557,16567,16571,16593],{"__ignoreMap":88},[92,16534,16535,16537,16539,16541,16543],{"class":94,"line":95},[92,16536,474],{"class":102},[92,16538,1543],{"class":98},[92,16540,1546],{"class":102},[92,16542,309],{"class":119},[92,16544,1082],{"class":134},[92,16546,16547,16549,16551,16553,16555],{"class":94,"line":106},[92,16548,474],{"class":102},[92,16550,1557],{"class":98},[92,16552,1546],{"class":102},[92,16554,309],{"class":119},[92,16556,574],{"class":134},[92,16558,16559,16561,16563,16565],{"class":94,"line":113},[92,16560,1501],{"class":98},[92,16562,474],{"class":102},[92,16564,1572],{"class":119},[92,16566,1082],{"class":134},[92,16568,16569],{"class":94,"line":138},[92,16570,110],{"emptyLinePlaceholder":109},[92,16572,16573,16575,16577,16579,16581,16583,16585,16587,16589,16591],{"class":94,"line":143},[92,16574,1583],{"class":119},[92,16576,126],{"class":98},[92,16578,1588],{"class":102},[92,16580,1591],{"class":119},[92,16582,1495],{"class":98},[92,16584,1596],{"class":119},[92,16586,1599],{"class":98},[92,16588,331],{"class":102},[92,16590,309],{"class":119},[92,16592,1606],{"class":134},[92,16594,16595,16597,16599,16601,16603,16605,16607],{"class":94,"line":149},[92,16596,1611],{"class":119},[92,16598,126],{"class":98},[92,16600,295],{"class":102},[92,16602,1618],{"class":98},[92,16604,1546],{"class":102},[92,16606,689],{"class":119},[92,16608,1625],{"class":134},[242,16610,1629],{"id":1628},[11,16612,1632,16613,1636,16615,1640,16617,1644,16619,1647,16621,1651,16623,987,16625,1656,16627,1660,16629,1663],{},[15,16614,1635],{},[15,16616,1639],{},[1511,16618,1643],{},[15,16620,23],{},[15,16622,1650],{},[15,16624,23],{},[15,16626,390],{},[15,16628,1659],{},[15,16630,390],{},[83,16632,16633],{"className":85,"code":1666,"language":87,"meta":88,"style":88},[15,16634,16635,16659,16675,16691,16707],{"__ignoreMap":88},[92,16636,16637,16639,16641,16643,16645,16647,16649,16651,16653,16655,16657],{"class":94,"line":95},[92,16638,1673],{"class":119},[92,16640,126],{"class":98},[92,16642,1678],{"class":119},[92,16644,1681],{"class":98},[92,16646,1684],{"class":102},[92,16648,1687],{"class":98},[92,16650,1690],{"class":171},[92,16652,903],{"class":98},[92,16654,1695],{"class":171},[92,16656,309],{"class":119},[92,16658,1700],{"class":134},[92,16660,16661,16663,16665,16667,16669,16671,16673],{"class":94,"line":106},[92,16662,1705],{"class":119},[92,16664,126],{"class":98},[92,16666,1710],{"class":119},[92,16668,1713],{"class":98},[92,16670,1716],{"class":171},[92,16672,1719],{"class":119},[92,16674,1722],{"class":134},[92,16676,16677,16679,16681,16683,16685,16687,16689],{"class":94,"line":113},[92,16678,1705],{"class":119},[92,16680,126],{"class":98},[92,16682,1710],{"class":119},[92,16684,1733],{"class":98},[92,16686,1716],{"class":171},[92,16688,1719],{"class":119},[92,16690,1740],{"class":134},[92,16692,16693,16695,16697,16699,16701,16703,16705],{"class":94,"line":138},[92,16694,1745],{"class":119},[92,16696,1748],{"class":171},[92,16698,1751],{"class":119},[92,16700,1754],{"class":98},[92,16702,1757],{"class":102},[92,16704,1719],{"class":119},[92,16706,1762],{"class":134},[92,16708,16709,16711,16713,16715,16717,16719,16721,16723],{"class":94,"line":143},[92,16710,1767],{"class":119},[92,16712,126],{"class":98},[92,16714,1772],{"class":119},[92,16716,1659],{"class":98},[92,16718,1777],{"class":119},[92,16720,1659],{"class":98},[92,16722,1782],{"class":119},[92,16724,1785],{"class":134},[242,16726,1789],{"id":1788},[11,16728,1792,16729,1796,16731,1800,16733,1804,16735,195,16737,195,16739,195,16741,195,16743,195,16745,1823,16747,1827,16749,1831],{},[15,16730,1795],{},[1511,16732,1799],{},[15,16734,1803],{},[15,16736,1807],{},[15,16738,1810],{},[15,16740,1813],{},[15,16742,1816],{},[15,16744,1819],{},[15,16746,1822],{},[15,16748,1826],{},[15,16750,1830],{},[83,16752,16753],{"className":85,"code":1834,"language":87,"meta":88,"style":88},[15,16754,16755,16797,16801,16813,16825,16837,16841],{"__ignoreMap":88},[92,16756,16757,16759,16761,16763,16765,16767,16769,16771,16773,16775,16777,16779,16781,16783,16785,16787,16789,16791,16793,16795],{"class":94,"line":95},[92,16758,1841],{"class":119},[92,16760,1844],{"class":171},[92,16762,1019],{"class":98},[92,16764,1849],{"class":102},[92,16766,195],{"class":119},[92,16768,198],{"class":171},[92,16770,1019],{"class":98},[92,16772,1225],{"class":102},[92,16774,1751],{"class":119},[92,16776,1795],{"class":98},[92,16778,347],{"class":119},[92,16780,198],{"class":171},[92,16782,1019],{"class":98},[92,16784,1870],{"class":102},[92,16786,195],{"class":119},[92,16788,203],{"class":171},[92,16790,1019],{"class":98},[92,16792,856],{"class":102},[92,16794,1881],{"class":119},[92,16796,1884],{"class":134},[92,16798,16799],{"class":94,"line":106},[92,16800,110],{"emptyLinePlaceholder":109},[92,16802,16803,16805,16807,16809,16811],{"class":94,"line":113},[92,16804,1235],{"class":102},[92,16806,1895],{"class":98},[92,16808,856],{"class":102},[92,16810,211],{"class":119},[92,16812,1902],{"class":134},[92,16814,16815,16817,16819,16821,16823],{"class":94,"line":138},[92,16816,1235],{"class":102},[92,16818,1909],{"class":98},[92,16820,1849],{"class":102},[92,16822,211],{"class":119},[92,16824,1916],{"class":134},[92,16826,16827,16829,16831,16833,16835],{"class":94,"line":143},[92,16828,68],{"class":102},[92,16830,1923],{"class":98},[92,16832,1926],{"class":102},[92,16834,309],{"class":119},[92,16836,1931],{"class":134},[92,16838,16839],{"class":94,"line":149},[92,16840,110],{"emptyLinePlaceholder":109},[92,16842,16843,16845,16847,16849,16851],{"class":94,"line":155},[92,16844,1940],{"class":119},[92,16846,1826],{"class":98},[92,16848,1945],{"class":102},[92,16850,309],{"class":119},[92,16852,1950],{"class":134},[11,16854,1953,16855,1956,16857,834,16859,1956,16861,834,16863,1967,16865,1956,16867,1972],{},[15,16856,1165],{},[15,16858,1959],{},[15,16860,529],{},[15,16862,1795],{},[15,16864,1966],{},[15,16866,1495],{},[15,16868,1498],{},[39,16870,1976],{"id":1975},[242,16872,1980],{"id":1979},[11,16874,1983,16875,834,16877,1989,16879,1993,16881,1997,16883,2001,16885,2005],{},[15,16876,175],{},[15,16878,1988],{},[15,16880,1992],{},[15,16882,1996],{},[15,16884,2000],{},[15,16886,2004],{},[83,16888,16889],{"className":85,"code":2008,"language":87,"meta":88,"style":88},[15,16890,16891,16901,16911,16927,16941,16959,16963,16983,16987,16997,17013,17021,17025,17037,17041],{"__ignoreMap":88},[92,16892,16893,16895,16897,16899],{"class":94,"line":95},[92,16894,1705],{"class":119},[92,16896,126],{"class":98},[92,16898,271],{"class":171},[92,16900,229],{"class":119},[92,16902,16903,16905,16907,16909],{"class":94,"line":106},[92,16904,60],{"class":102},[92,16906,2027],{"class":171},[92,16908,1719],{"class":119},[92,16910,2032],{"class":134},[92,16912,16913,16915,16917,16919,16921,16923,16925],{"class":94,"line":113},[92,16914,60],{"class":102},[92,16916,2039],{"class":171},[92,16918,2042],{"class":119},[92,16920,175],{"class":102},[92,16922,178],{"class":171},[92,16924,946],{"class":119},[92,16926,2051],{"class":134},[92,16928,16929,16931,16933,16935,16937,16939],{"class":94,"line":138},[92,16930,60],{"class":102},[92,16932,2058],{"class":171},[92,16934,2042],{"class":119},[92,16936,2063],{"class":171},[92,16938,1719],{"class":119},[92,16940,2068],{"class":134},[92,16942,16943,16945,16947,16949,16951,16953,16955,16957],{"class":94,"line":143},[92,16944,60],{"class":102},[92,16946,2075],{"class":171},[92,16948,2078],{"class":119},[92,16950,1996],{"class":98},[92,16952,2083],{"class":119},[92,16954,2086],{"class":171},[92,16956,975],{"class":119},[92,16958,2091],{"class":134},[92,16960,16961],{"class":94,"line":149},[92,16962,110],{"emptyLinePlaceholder":109},[92,16964,16965,16967,16969,16971,16973,16975,16977,16979,16981],{"class":94,"line":155},[92,16966,2100],{"class":119},[92,16968,126],{"class":98},[92,16970,2105],{"class":171},[92,16972,2108],{"class":98},[92,16974,2111],{"class":119},[92,16976,81],{"class":98},[92,16978,1329],{"class":171},[92,16980,309],{"class":119},[92,16982,2120],{"class":134},[92,16984,16985],{"class":94,"line":161},[92,16986,110],{"emptyLinePlaceholder":109},[92,16988,16989,16991,16993,16995],{"class":94,"line":166},[92,16990,2129],{"class":119},[92,16992,126],{"class":98},[92,16994,2134],{"class":171},[92,16996,2137],{"class":98},[92,16998,16999,17001,17003,17005,17007,17009,17011],{"class":94,"line":187},[92,17000,2142],{"class":171},[92,17002,11],{"class":2145},[92,17004,2148],{"class":171},[92,17006,2042],{"class":119},[92,17008,2153],{"class":171},[92,17010,11],{"class":2145},[92,17012,2158],{"class":171},[92,17014,17015,17017,17019],{"class":94,"line":217},[92,17016,2163],{"class":98},[92,17018,2166],{"class":119},[92,17020,2169],{"class":134},[92,17022,17023],{"class":94,"line":712},[92,17024,110],{"emptyLinePlaceholder":109},[92,17026,17027,17029,17031,17033,17035],{"class":94,"line":730},[92,17028,2178],{"class":119},[92,17030,126],{"class":98},[92,17032,2183],{"class":171},[92,17034,2186],{"class":98},[92,17036,2189],{"class":171},[92,17038,17039],{"class":94,"line":747},[92,17040,2194],{"class":171},[92,17042,17043,17045,17047],{"class":94,"line":763},[92,17044,2199],{"class":98},[92,17046,2202],{"class":119},[92,17048,2205],{"class":134},[242,17050,2209],{"id":2208},[11,17052,2212,17053,2216,17055,2220],{},[1511,17054,2215],{},[15,17056,2219],{},[83,17058,17059],{"className":85,"code":2223,"language":87,"meta":88,"style":88},[15,17060,17061,17071,17081,17093],{"__ignoreMap":88},[92,17062,17063,17065,17067,17069],{"class":94,"line":95},[92,17064,2230],{"class":119},[92,17066,126],{"class":98},[92,17068,2235],{"class":171},[92,17070,229],{"class":119},[92,17072,17073,17075,17077,17079],{"class":94,"line":106},[92,17074,2242],{"class":119},[92,17076,554],{"class":102},[92,17078,2247],{"class":119},[92,17080,2250],{"class":134},[92,17082,17083,17085,17087,17089,17091],{"class":94,"line":113},[92,17084,2242],{"class":119},[92,17086,1966],{"class":98},[92,17088,68],{"class":102},[92,17090,2261],{"class":119},[92,17092,2264],{"class":134},[92,17094,17095,17097,17099,17101,17103,17105,17107],{"class":94,"line":138},[92,17096,2242],{"class":119},[92,17098,68],{"class":102},[92,17100,1751],{"class":119},[92,17102,126],{"class":98},[92,17104,192],{"class":171},[92,17106,2279],{"class":119},[92,17108,2282],{"class":134},[242,17110,2286],{"id":2285},[11,17112,2289,17113,2293,17115,2297,17117,81],{},[15,17114,2292],{},[15,17116,2296],{},[15,17118,2300],{},[83,17120,17121],{"className":85,"code":2303,"language":87,"meta":88,"style":88},[15,17122,17123,17135,17147,17159,17171,17183,17195,17211,17215,17235,17251,17267,17283,17299,17315,17319,17339,17355,17371,17395,17407,17423,17427,17443,17467,17491,17507],{"__ignoreMap":88},[92,17124,17125,17127,17129,17131,17133],{"class":94,"line":95},[92,17126,2310],{"class":102},[92,17128,120],{"class":119},[92,17130,2315],{"class":171},[92,17132,2318],{"class":119},[92,17134,2321],{"class":134},[92,17136,17137,17139,17141,17143,17145],{"class":94,"line":106},[92,17138,2326],{"class":102},[92,17140,120],{"class":119},[92,17142,460],{"class":171},[92,17144,2333],{"class":119},[92,17146,2336],{"class":134},[92,17148,17149,17151,17153,17155,17157],{"class":94,"line":113},[92,17150,2341],{"class":102},[92,17152,120],{"class":119},[92,17154,2346],{"class":171},[92,17156,2333],{"class":119},[92,17158,2351],{"class":134},[92,17160,17161,17163,17165,17167,17169],{"class":94,"line":138},[92,17162,2356],{"class":102},[92,17164,120],{"class":119},[92,17166,2315],{"class":171},[92,17168,2333],{"class":119},[92,17170,2365],{"class":134},[92,17172,17173,17175,17177,17179,17181],{"class":94,"line":143},[92,17174,2370],{"class":102},[92,17176,120],{"class":119},[92,17178,2375],{"class":171},[92,17180,2378],{"class":119},[92,17182,2381],{"class":134},[92,17184,17185,17187,17189,17191,17193],{"class":94,"line":149},[92,17186,2386],{"class":102},[92,17188,120],{"class":119},[92,17190,2391],{"class":171},[92,17192,2394],{"class":119},[92,17194,2397],{"class":134},[92,17196,17197,17199,17201,17203,17205,17207,17209],{"class":94,"line":155},[92,17198,2386],{"class":102},[92,17200,120],{"class":119},[92,17202,2406],{"class":171},[92,17204,195],{"class":119},[92,17206,2411],{"class":171},[92,17208,2414],{"class":119},[92,17210,2417],{"class":134},[92,17212,17213],{"class":94,"line":161},[92,17214,110],{"emptyLinePlaceholder":109},[92,17216,17217,17219,17221,17223,17225,17227,17229,17231,17233],{"class":94,"line":166},[92,17218,2426],{"class":102},[92,17220,120],{"class":119},[92,17222,2315],{"class":171},[92,17224,195],{"class":119},[92,17226,68],{"class":102},[92,17228,195],{"class":119},[92,17230,1448],{"class":102},[92,17232,2441],{"class":119},[92,17234,2444],{"class":134},[92,17236,17237,17239,17241,17243,17245,17247,17249],{"class":94,"line":187},[92,17238,2449],{"class":102},[92,17240,120],{"class":119},[92,17242,2315],{"class":171},[92,17244,195],{"class":119},[92,17246,2458],{"class":171},[92,17248,2461],{"class":119},[92,17250,2464],{"class":134},[92,17252,17253,17255,17257,17259,17261,17263,17265],{"class":94,"line":217},[92,17254,2469],{"class":102},[92,17256,120],{"class":119},[92,17258,2315],{"class":171},[92,17260,195],{"class":119},[92,17262,2458],{"class":171},[92,17264,2441],{"class":119},[92,17266,2482],{"class":134},[92,17268,17269,17271,17273,17275,17277,17279,17281],{"class":94,"line":712},[92,17270,2487],{"class":102},[92,17272,120],{"class":119},[92,17274,2315],{"class":171},[92,17276,195],{"class":119},[92,17278,2496],{"class":171},[92,17280,599],{"class":119},[92,17282,2501],{"class":134},[92,17284,17285,17287,17289,17291,17293,17295,17297],{"class":94,"line":730},[92,17286,2506],{"class":102},[92,17288,120],{"class":119},[92,17290,2315],{"class":171},[92,17292,195],{"class":119},[92,17294,2515],{"class":171},[92,17296,131],{"class":119},[92,17298,2501],{"class":134},[92,17300,17301,17303,17305,17307,17309,17311,17313],{"class":94,"line":747},[92,17302,2524],{"class":102},[92,17304,120],{"class":119},[92,17306,2315],{"class":171},[92,17308,195],{"class":119},[92,17310,2533],{"class":171},[92,17312,599],{"class":119},[92,17314,2501],{"class":134},[92,17316,17317],{"class":94,"line":763},[92,17318,110],{"emptyLinePlaceholder":109},[92,17320,17321,17323,17325,17327,17329,17331,17333,17335,17337],{"class":94,"line":780},[92,17322,2546],{"class":102},[92,17324,120],{"class":119},[92,17326,2458],{"class":171},[92,17328,195],{"class":119},[92,17330,2555],{"class":171},[92,17332,195],{"class":119},[92,17334,2315],{"class":171},[92,17336,131],{"class":119},[92,17338,2564],{"class":134},[92,17340,17341,17343,17345,17347,17349,17351,17353],{"class":94,"line":785},[92,17342,2569],{"class":102},[92,17344,120],{"class":119},[92,17346,2315],{"class":171},[92,17348,195],{"class":119},[92,17350,2458],{"class":171},[92,17352,613],{"class":119},[92,17354,2582],{"class":134},[92,17356,17357,17359,17361,17363,17365,17367,17369],{"class":94,"line":2585},[92,17358,2588],{"class":102},[92,17360,120],{"class":119},[92,17362,2593],{"class":171},[92,17364,195],{"class":119},[92,17366,1448],{"class":102},[92,17368,2414],{"class":119},[92,17370,2602],{"class":134},[92,17372,17373,17375,17377,17379,17381,17383,17385,17387,17389,17391,17393],{"class":94,"line":2605},[92,17374,2608],{"class":102},[92,17376,120],{"class":119},[92,17378,2613],{"class":171},[92,17380,195],{"class":119},[92,17382,1448],{"class":102},[92,17384,195],{"class":119},[92,17386,739],{"class":171},[92,17388,195],{"class":119},[92,17390,2626],{"class":102},[92,17392,653],{"class":119},[92,17394,2631],{"class":134},[92,17396,17397,17399,17401,17403,17405],{"class":94,"line":2634},[92,17398,2637],{"class":102},[92,17400,120],{"class":119},[92,17402,2642],{"class":171},[92,17404,2645],{"class":119},[92,17406,2648],{"class":134},[92,17408,17409,17411,17413,17415,17417,17419,17421],{"class":94,"line":2651},[92,17410,2654],{"class":102},[92,17412,120],{"class":119},[92,17414,2659],{"class":171},[92,17416,195],{"class":119},[92,17418,354],{"class":102},[92,17420,2461],{"class":119},[92,17422,2668],{"class":134},[92,17424,17425],{"class":94,"line":2671},[92,17426,110],{"emptyLinePlaceholder":109},[92,17428,17429,17431,17433,17435,17437,17439,17441],{"class":94,"line":2676},[92,17430,2679],{"class":102},[92,17432,120],{"class":119},[92,17434,2684],{"class":171},[92,17436,195],{"class":119},[92,17438,2689],{"class":171},[92,17440,2441],{"class":119},[92,17442,2694],{"class":134},[92,17444,17445,17447,17449,17451,17453,17455,17457,17459,17461,17463,17465],{"class":94,"line":2697},[92,17446,2700],{"class":102},[92,17448,120],{"class":119},[92,17450,2705],{"class":171},[92,17452,2708],{"class":119},[92,17454,1844],{"class":171},[92,17456,195],{"class":119},[92,17458,198],{"class":171},[92,17460,195],{"class":119},[92,17462,203],{"class":171},[92,17464,495],{"class":119},[92,17466,2723],{"class":134},[92,17468,17469,17471,17473,17475,17477,17479,17481,17483,17485,17487,17489],{"class":94,"line":2726},[92,17470,2729],{"class":102},[92,17472,120],{"class":119},[92,17474,2734],{"class":171},[92,17476,195],{"class":119},[92,17478,772],{"class":171},[92,17480,195],{"class":119},[92,17482,1448],{"class":102},[92,17484,195],{"class":119},[92,17486,2747],{"class":102},[92,17488,653],{"class":119},[92,17490,2752],{"class":134},[92,17492,17493,17495,17497,17499,17501,17503,17505],{"class":94,"line":2755},[92,17494,2758],{"class":102},[92,17496,120],{"class":119},[92,17498,2763],{"class":102},[92,17500,195],{"class":119},[92,17502,354],{"class":102},[92,17504,2770],{"class":119},[92,17506,2773],{"class":134},[92,17508,17509,17511,17513,17515,17517],{"class":94,"line":2776},[92,17510,2779],{"class":102},[92,17512,120],{"class":119},[92,17514,2784],{"class":171},[92,17516,653],{"class":119},[92,17518,2789],{"class":134},[242,17520,2793],{"id":2792},[11,17522,2796,17523,2800],{},[15,17524,2799],{},[83,17526,17527],{"className":85,"code":2803,"language":87,"meta":88,"style":88},[15,17528,17529,17541,17553,17565],{"__ignoreMap":88},[92,17530,17531,17533,17535,17537,17539],{"class":94,"line":95},[92,17532,2810],{"class":102},[92,17534,120],{"class":119},[92,17536,2815],{"class":171},[92,17538,131],{"class":119},[92,17540,2820],{"class":134},[92,17542,17543,17545,17547,17549,17551],{"class":94,"line":106},[92,17544,2825],{"class":102},[92,17546,120],{"class":119},[92,17548,2830],{"class":171},[92,17550,800],{"class":119},[92,17552,2835],{"class":134},[92,17554,17555,17557,17559,17561,17563],{"class":94,"line":113},[92,17556,2840],{"class":102},[92,17558,120],{"class":119},[92,17560,2845],{"class":171},[92,17562,800],{"class":119},[92,17564,2850],{"class":134},[92,17566,17567,17569,17571,17573,17575,17577,17579],{"class":94,"line":138},[92,17568,2855],{"class":102},[92,17570,120],{"class":119},[92,17572,2860],{"class":171},[92,17574,2863],{"class":102},[92,17576,178],{"class":171},[92,17578,800],{"class":119},[92,17580,2870],{"class":134},[11,17582,2873,17583,1369,17585,2879,17587,2883,17589,2886,17591,2890,17593,2894],{},[15,17584,2876],{},[15,17586,554],{},[15,17588,2882],{},[15,17590,554],{},[15,17592,2889],{},[15,17594,2893],{},[39,17596,2898],{"id":2897},[242,17598,2902],{"id":2901},[11,17600,2905,17601,2908,17603,2912,17605,2916,17607,2920,17609,2924],{},[15,17602,383],{},[1511,17604,2911],{},[15,17606,2915],{},[15,17608,2919],{},[15,17610,2923],{},[83,17612,17613],{"className":85,"code":2927,"language":87,"meta":88,"style":88},[15,17614,17615,17637,17663,17697,17705,17727,17747,17751],{"__ignoreMap":88},[92,17616,17617,17619,17621,17623,17625,17627,17629,17631,17633,17635],{"class":94,"line":95},[92,17618,2934],{"class":119},[92,17620,126],{"class":98},[92,17622,347],{"class":119},[92,17624,68],{"class":102},[92,17626,195],{"class":119},[92,17628,354],{"class":102},[92,17630,195],{"class":119},[92,17632,1448],{"class":102},[92,17634,2951],{"class":119},[92,17636,2954],{"class":134},[92,17638,17639,17641,17643,17645,17647,17649,17651,17653,17655,17657,17659,17661],{"class":94,"line":106},[92,17640,2959],{"class":119},[92,17642,126],{"class":98},[92,17644,347],{"class":119},[92,17646,1016],{"class":171},[92,17648,1019],{"class":98},[92,17650,271],{"class":171},[92,17652,195],{"class":119},[92,17654,2974],{"class":171},[92,17656,1019],{"class":98},[92,17658,2979],{"class":102},[92,17660,1881],{"class":119},[92,17662,2984],{"class":134},[92,17664,17665,17667,17669,17671,17673,17675,17677,17679,17681,17683,17685,17687,17689,17691,17693,17695],{"class":94,"line":113},[92,17666,2989],{"class":119},[92,17668,126],{"class":98},[92,17670,347],{"class":119},[92,17672,554],{"class":102},[92,17674,1019],{"class":98},[92,17676,192],{"class":171},[92,17678,195],{"class":119},[92,17680,3004],{"class":171},[92,17682,1019],{"class":98},[92,17684,3009],{"class":171},[92,17686,195],{"class":119},[92,17688,1463],{"class":102},[92,17690,1019],{"class":98},[92,17692,3018],{"class":171},[92,17694,3021],{"class":119},[92,17696,3024],{"class":134},[92,17698,17699,17701,17703],{"class":94,"line":138},[92,17700,3029],{"class":119},[92,17702,126],{"class":98},[92,17704,3034],{"class":119},[92,17706,17707,17709,17711,17713,17715,17717,17719,17721,17723,17725],{"class":94,"line":143},[92,17708,3039],{"class":119},[92,17710,1016],{"class":171},[92,17712,1019],{"class":98},[92,17714,271],{"class":171},[92,17716,3048],{"class":119},[92,17718,2974],{"class":171},[92,17720,1019],{"class":98},[92,17722,2979],{"class":102},[92,17724,3057],{"class":119},[92,17726,3060],{"class":134},[92,17728,17729,17731,17733,17735,17737,17739,17741,17743,17745],{"class":94,"line":149},[92,17730,3039],{"class":119},[92,17732,1016],{"class":171},[92,17734,1019],{"class":98},[92,17736,3071],{"class":171},[92,17738,195],{"class":119},[92,17740,2974],{"class":171},[92,17742,1019],{"class":98},[92,17744,3080],{"class":102},[92,17746,3083],{"class":119},[92,17748,17749],{"class":94,"line":155},[92,17750,1034],{"class":119},[92,17752,17753,17755,17757,17759,17761,17763],{"class":94,"line":161},[92,17754,3092],{"class":119},[92,17756,68],{"class":102},[92,17758,3097],{"class":119},[92,17760,1016],{"class":171},[92,17762,2261],{"class":119},[92,17764,3104],{"class":134},[11,17766,17767],{},[3108,17768],{"alt":3110,"src":3111},[242,17770,3115],{"id":3114},[11,17772,3118,17773,3122,17775,3126,17777,834,17779,3132,17781,834,17783,3139],{},[15,17774,3121],{},[15,17776,3125],{},[15,17778,3129],{},[15,17780,3125],{},[15,17782,3135],{},[15,17784,3138],{},[83,17786,17787],{"className":85,"code":3142,"language":87,"meta":88,"style":88},[15,17788,17789,17809,17821,17837,17845,17853,17865,17869,17877,17889,17905,17917],{"__ignoreMap":88},[92,17790,17791,17793,17795,17797,17799,17801,17803,17805,17807],{"class":94,"line":95},[92,17792,321],{"class":119},[92,17794,126],{"class":98},[92,17796,347],{"class":119},[92,17798,68],{"class":102},[92,17800,195],{"class":119},[92,17802,354],{"class":102},[92,17804,195],{"class":119},[92,17806,1448],{"class":102},[92,17808,1034],{"class":119},[92,17810,17811,17813,17815,17817,17819],{"class":94,"line":106},[92,17812,3169],{"class":119},[92,17814,126],{"class":98},[92,17816,1926],{"class":102},[92,17818,3176],{"class":119},[92,17820,3179],{"class":134},[92,17822,17823,17825,17827,17829,17831,17833,17835],{"class":94,"line":113},[92,17824,3184],{"class":102},[92,17826,3187],{"class":119},[92,17828,1463],{"class":102},[92,17830,195],{"class":119},[92,17832,1235],{"class":102},[92,17834,599],{"class":119},[92,17836,3198],{"class":134},[92,17838,17839,17841,17843],{"class":94,"line":138},[92,17840,3203],{"class":102},[92,17842,3206],{"class":119},[92,17844,3209],{"class":134},[92,17846,17847,17849,17851],{"class":94,"line":143},[92,17848,3214],{"class":102},[92,17850,3217],{"class":119},[92,17852,3220],{"class":134},[92,17854,17855,17857,17859,17861,17863],{"class":94,"line":149},[92,17856,3225],{"class":102},[92,17858,3187],{"class":119},[92,17860,554],{"class":102},[92,17862,599],{"class":119},[92,17864,3234],{"class":134},[92,17866,17867],{"class":94,"line":155},[92,17868,110],{"emptyLinePlaceholder":109},[92,17870,17871,17873,17875],{"class":94,"line":161},[92,17872,3243],{"class":102},[92,17874,3246],{"class":119},[92,17876,3249],{"class":134},[92,17878,17879,17881,17883,17885,17887],{"class":94,"line":166},[92,17880,3254],{"class":102},[92,17882,120],{"class":119},[92,17884,1448],{"class":102},[92,17886,3261],{"class":119},[92,17888,3264],{"class":134},[92,17890,17891,17893,17895,17897,17899,17901,17903],{"class":94,"line":187},[92,17892,3254],{"class":102},[92,17894,120],{"class":119},[92,17896,3273],{"class":171},[92,17898,3276],{"class":119},[92,17900,474],{"class":102},[92,17902,800],{"class":119},[92,17904,3283],{"class":134},[92,17906,17907,17909,17911,17913,17915],{"class":94,"line":217},[92,17908,3288],{"class":102},[92,17910,120],{"class":119},[92,17912,1448],{"class":102},[92,17914,3295],{"class":119},[92,17916,3298],{"class":134},[92,17918,17919,17921,17923,17925,17927],{"class":94,"line":712},[92,17920,1087],{"class":102},[92,17922,120],{"class":119},[92,17924,3004],{"class":171},[92,17926,3309],{"class":119},[92,17928,3312],{"class":134},[242,17930,3316],{"id":3315},[11,17932,3319,17933,3323,17935,3327,17937,3331,17939,3335,17941,3338,17943,3342,17945,3345,17947,3348],{},[15,17934,3322],{},[15,17936,3326],{},[15,17938,3330],{},[1511,17940,3334],{},[15,17942,3326],{},[15,17944,3341],{},[15,17946,3322],{},[15,17948,390],{},[83,17950,17951],{"className":85,"code":3351,"language":87,"meta":88,"style":88},[15,17952,17953,17977,17981,17989,17997,18021,18029,18037,18041,18059,18077,18099,18119],{"__ignoreMap":88},[92,17954,17955,17957,17959,17961,17963,17965,17967,17969,17971,17973,17975],{"class":94,"line":95},[92,17956,3358],{"class":119},[92,17958,126],{"class":98},[92,17960,347],{"class":119},[92,17962,1463],{"class":102},[92,17964,195],{"class":119},[92,17966,1448],{"class":102},[92,17968,195],{"class":119},[92,17970,3373],{"class":102},[92,17972,195],{"class":119},[92,17974,68],{"class":102},[92,17976,1034],{"class":119},[92,17978,17979],{"class":94,"line":106},[92,17980,110],{"emptyLinePlaceholder":109},[92,17982,17983,17985,17987],{"class":94,"line":113},[92,17984,3388],{"class":102},[92,17986,3391],{"class":119},[92,17988,3394],{"class":134},[92,17990,17991,17993,17995],{"class":94,"line":138},[92,17992,3399],{"class":102},[92,17994,3402],{"class":119},[92,17996,3405],{"class":134},[92,17998,17999,18001,18003,18005,18007,18009,18011,18013,18015,18017,18019],{"class":94,"line":143},[92,18000,3410],{"class":102},[92,18002,486],{"class":119},[92,18004,1844],{"class":171},[92,18006,1019],{"class":98},[92,18008,1849],{"class":102},[92,18010,195],{"class":119},[92,18012,198],{"class":171},[92,18014,1019],{"class":98},[92,18016,1225],{"class":102},[92,18018,1064],{"class":119},[92,18020,3431],{"class":134},[92,18022,18023,18025,18027],{"class":94,"line":149},[92,18024,3436],{"class":102},[92,18026,3439],{"class":119},[92,18028,3442],{"class":134},[92,18030,18031,18033,18035],{"class":94,"line":155},[92,18032,3447],{"class":102},[92,18034,3450],{"class":119},[92,18036,3453],{"class":134},[92,18038,18039],{"class":94,"line":161},[92,18040,110],{"emptyLinePlaceholder":109},[92,18042,18043,18045,18047,18049,18051,18053,18055,18057],{"class":94,"line":166},[92,18044,3322],{"class":102},[92,18046,120],{"class":119},[92,18048,3466],{"class":98},[92,18050,3469],{"class":119},[92,18052,1959],{"class":98},[92,18054,1225],{"class":102},[92,18056,3476],{"class":119},[92,18058,3479],{"class":134},[92,18060,18061,18063,18065,18067,18069,18071,18073,18075],{"class":94,"line":187},[92,18062,3326],{"class":102},[92,18064,3486],{"class":119},[92,18066,3466],{"class":98},[92,18068,3469],{"class":119},[92,18070,1599],{"class":98},[92,18072,856],{"class":102},[92,18074,599],{"class":119},[92,18076,3499],{"class":134},[92,18078,18079,18081,18083,18085,18087,18089,18091,18093,18095,18097],{"class":94,"line":217},[92,18080,3399],{"class":102},[92,18082,120],{"class":119},[92,18084,3326],{"class":102},[92,18086,3486],{"class":119},[92,18088,3466],{"class":98},[92,18090,3469],{"class":119},[92,18092,1599],{"class":98},[92,18094,856],{"class":102},[92,18096,3520],{"class":119},[92,18098,3523],{"class":134},[92,18100,18101,18103,18105,18107,18109,18111,18113,18115,18117],{"class":94,"line":712},[92,18102,3330],{"class":102},[92,18104,3486],{"class":119},[92,18106,3466],{"class":98},[92,18108,3534],{"class":119},[92,18110,1795],{"class":98},[92,18112,3539],{"class":119},[92,18114,554],{"class":102},[92,18116,653],{"class":119},[92,18118,3546],{"class":134},[92,18120,18121,18123,18125,18127,18129,18131,18133,18135,18137,18139],{"class":94,"line":730},[92,18122,3551],{"class":102},[92,18124,3486],{"class":119},[92,18126,3556],{"class":98},[92,18128,3559],{"class":119},[92,18130,1807],{"class":98},[92,18132,3564],{"class":119},[92,18134,1188],{"class":98},[92,18136,1286],{"class":102},[92,18138,3571],{"class":119},[92,18140,3574],{"class":134},[242,18142,3578],{"id":3577},[11,18144,3581,18145,3585,18147,3588,18149,3591,18151,3594],{},[15,18146,3584],{},[15,18148,1795],{},[15,18150,3584],{},[15,18152,1795],{},[83,18154,18155],{"className":85,"code":3597,"language":87,"meta":88,"style":88},[15,18156,18157,18181,18205,18229,18233,18269,18289,18321,18333,18349,18353,18381,18413,18445,18465,18481,18497,18517,18525,18545],{"__ignoreMap":88},[92,18158,18159,18161,18163,18165,18167,18169,18171,18173,18175,18177,18179],{"class":94,"line":95},[92,18160,3584],{"class":102},[92,18162,486],{"class":119},[92,18164,68],{"class":102},[92,18166,195],{"class":119},[92,18168,354],{"class":102},[92,18170,3614],{"class":119},[92,18172,1448],{"class":102},[92,18174,195],{"class":119},[92,18176,3621],{"class":102},[92,18178,3624],{"class":119},[92,18180,3627],{"class":134},[92,18182,18183,18185,18187,18189,18191,18193,18195,18197,18199,18201,18203],{"class":94,"line":106},[92,18184,3584],{"class":102},[92,18186,486],{"class":119},[92,18188,1844],{"class":171},[92,18190,1019],{"class":98},[92,18192,1849],{"class":102},[92,18194,3614],{"class":119},[92,18196,1844],{"class":171},[92,18198,1019],{"class":98},[92,18200,1225],{"class":102},[92,18202,627],{"class":119},[92,18204,3652],{"class":134},[92,18206,18207,18209,18211,18213,18215,18217,18219,18221,18223,18225,18227],{"class":94,"line":113},[92,18208,3657],{"class":102},[92,18210,486],{"class":119},[92,18212,1844],{"class":171},[92,18214,195],{"class":119},[92,18216,198],{"class":171},[92,18218,3614],{"class":119},[92,18220,68],{"class":102},[92,18222,195],{"class":119},[92,18224,354],{"class":102},[92,18226,3676],{"class":119},[92,18228,3679],{"class":134},[92,18230,18231],{"class":94,"line":138},[92,18232,110],{"emptyLinePlaceholder":109},[92,18234,18235,18237,18239,18241,18243,18245,18247,18249,18251,18253,18255,18257,18259,18261,18263,18265,18267],{"class":94,"line":143},[92,18236,3688],{"class":102},[92,18238,486],{"class":119},[92,18240,68],{"class":102},[92,18242,195],{"class":119},[92,18244,354],{"class":102},[92,18246,195],{"class":119},[92,18248,1448],{"class":102},[92,18250,195],{"class":119},[92,18252,3621],{"class":102},[92,18254,195],{"class":119},[92,18256,1463],{"class":102},[92,18258,3711],{"class":119},[92,18260,68],{"class":102},[92,18262,195],{"class":119},[92,18264,354],{"class":102},[92,18266,433],{"class":119},[92,18268,3722],{"class":134},[92,18270,18271,18273,18275,18277,18279,18281,18283,18285,18287],{"class":94,"line":149},[92,18272,3727],{"class":102},[92,18274,3486],{"class":119},[92,18276,68],{"class":102},[92,18278,195],{"class":119},[92,18280,354],{"class":102},[92,18282,2708],{"class":119},[92,18284,772],{"class":171},[92,18286,1064],{"class":119},[92,18288,3744],{"class":134},[92,18290,18291,18293,18295,18297,18299,18301,18303,18305,18307,18309,18311,18313,18315,18317,18319],{"class":94,"line":155},[92,18292,3749],{"class":102},[92,18294,486],{"class":119},[92,18296,68],{"class":102},[92,18298,195],{"class":119},[92,18300,354],{"class":102},[92,18302,195],{"class":119},[92,18304,1448],{"class":102},[92,18306,195],{"class":119},[92,18308,3621],{"class":102},[92,18310,195],{"class":119},[92,18312,1463],{"class":102},[92,18314,3711],{"class":119},[92,18316,354],{"class":102},[92,18318,2378],{"class":119},[92,18320,3778],{"class":134},[92,18322,18323,18325,18327,18329,18331],{"class":94,"line":161},[92,18324,3783],{"class":102},[92,18326,3786],{"class":119},[92,18328,1016],{"class":171},[92,18330,2461],{"class":119},[92,18332,3793],{"class":134},[92,18334,18335,18337,18339,18341,18343,18345,18347],{"class":94,"line":166},[92,18336,3783],{"class":102},[92,18338,3786],{"class":119},[92,18340,2974],{"class":171},[92,18342,195],{"class":119},[92,18344,1016],{"class":171},[92,18346,448],{"class":119},[92,18348,3810],{"class":134},[92,18350,18351],{"class":94,"line":187},[92,18352,110],{"emptyLinePlaceholder":109},[92,18354,18355,18357,18359,18361,18363,18365,18367,18369,18371,18373,18375,18377,18379],{"class":94,"line":217},[92,18356,3819],{"class":102},[92,18358,486],{"class":119},[92,18360,68],{"class":102},[92,18362,195],{"class":119},[92,18364,68],{"class":102},[92,18366,195],{"class":119},[92,18368,354],{"class":102},[92,18370,195],{"class":119},[92,18372,1448],{"class":102},[92,18374,195],{"class":119},[92,18376,1448],{"class":102},[92,18378,3842],{"class":119},[92,18380,3845],{"class":134},[92,18382,18383,18385,18387,18389,18391,18393,18395,18397,18399,18401,18403,18405,18407,18409,18411],{"class":94,"line":712},[92,18384,3850],{"class":102},[92,18386,486],{"class":119},[92,18388,68],{"class":102},[92,18390,195],{"class":119},[92,18392,354],{"class":102},[92,18394,195],{"class":119},[92,18396,1448],{"class":102},[92,18398,195],{"class":119},[92,18400,3621],{"class":102},[92,18402,3614],{"class":119},[92,18404,354],{"class":102},[92,18406,195],{"class":119},[92,18408,3621],{"class":102},[92,18410,1064],{"class":119},[92,18412,3879],{"class":134},[92,18414,18415,18417,18419,18421,18423,18425,18427,18429,18431,18433,18435,18437,18439,18441,18443],{"class":94,"line":730},[92,18416,3884],{"class":102},[92,18418,486],{"class":119},[92,18420,68],{"class":102},[92,18422,195],{"class":119},[92,18424,354],{"class":102},[92,18426,195],{"class":119},[92,18428,1448],{"class":102},[92,18430,3614],{"class":119},[92,18432,354],{"class":102},[92,18434,195],{"class":119},[92,18436,1448],{"class":102},[92,18438,195],{"class":119},[92,18440,3621],{"class":102},[92,18442,3911],{"class":119},[92,18444,3914],{"class":134},[92,18446,18447,18449,18451,18453,18455,18457,18459,18461,18463],{"class":94,"line":747},[92,18448,3919],{"class":102},[92,18450,486],{"class":119},[92,18452,68],{"class":102},[92,18454,195],{"class":119},[92,18456,354],{"class":102},[92,18458,195],{"class":119},[92,18460,1448],{"class":102},[92,18462,3934],{"class":119},[92,18464,3937],{"class":134},[92,18466,18467,18469,18471,18473,18475,18477,18479],{"class":94,"line":763},[92,18468,3942],{"class":102},[92,18470,120],{"class":119},[92,18472,68],{"class":102},[92,18474,195],{"class":119},[92,18476,1463],{"class":102},[92,18478,3953],{"class":119},[92,18480,3956],{"class":134},[92,18482,18483,18485,18487,18489,18491,18493,18495],{"class":94,"line":780},[92,18484,3942],{"class":102},[92,18486,120],{"class":119},[92,18488,1844],{"class":171},[92,18490,195],{"class":119},[92,18492,3969],{"class":171},[92,18494,3972],{"class":119},[92,18496,3975],{"class":134},[92,18498,18499,18501,18503,18505,18507,18509,18511,18513,18515],{"class":94,"line":785},[92,18500,3980],{"class":102},[92,18502,120],{"class":119},[92,18504,554],{"class":102},[92,18506,195],{"class":119},[92,18508,1448],{"class":102},[92,18510,195],{"class":119},[92,18512,554],{"class":102},[92,18514,3995],{"class":119},[92,18516,3998],{"class":134},[92,18518,18519,18521,18523],{"class":94,"line":2585},[92,18520,4003],{"class":102},[92,18522,4006],{"class":119},[92,18524,4009],{"class":134},[92,18526,18527,18529,18531,18533,18535,18537,18539,18541,18543],{"class":94,"line":2605},[92,18528,4014],{"class":102},[92,18530,486],{"class":119},[92,18532,354],{"class":102},[92,18534,195],{"class":119},[92,18536,1448],{"class":102},[92,18538,195],{"class":119},[92,18540,3621],{"class":102},[92,18542,3934],{"class":119},[92,18544,4031],{"class":134},[92,18546,18547,18549,18551,18553,18555],{"class":94,"line":2634},[92,18548,4036],{"class":102},[92,18550,4039],{"class":119},[92,18552,4042],{"class":102},[92,18554,4045],{"class":119},[92,18556,4048],{"class":134},[242,18558,4052],{"id":4051},[11,18560,4055,18561,4059,18563,4063,18565,4066],{},[1511,18562,4058],{},[15,18564,4062],{},[15,18566,1368],{},[4068,18568,18569,18581],{},[4071,18570,18571],{},[4074,18572,18573,18575,18577,18579],{},[4077,18574,4079],{},[4077,18576,4082],{},[4077,18578,4085],{},[4077,18580,4088],{},[4090,18582,18583,18597,18611,18625,18637,18649,18661],{},[4074,18584,18585,18591,18593,18595],{},[4095,18586,18587,4100,18589],{},[15,18588,4099],{},[15,18590,4103],{},[4095,18592,4106],{},[4095,18594,4109],{},[4095,18596,4112],{},[4074,18598,18599,18605,18607,18609],{},[4095,18600,18601,4100,18603],{},[15,18602,4119],{},[15,18604,4122],{},[4095,18606,4106],{},[4095,18608,4109],{},[4095,18610,4129],{},[4074,18612,18613,18619,18621,18623],{},[4095,18614,18615,4100,18617],{},[15,18616,4136],{},[15,18618,4139],{},[4095,18620,4142],{},[4095,18622,4109],{},[4095,18624,4129],{},[4074,18626,18627,18631,18633,18635],{},[4095,18628,18629],{},[15,18630,4153],{},[4095,18632,4156],{},[4095,18634,4159],{},[4095,18636,4162],{},[4074,18638,18639,18643,18645,18647],{},[4095,18640,18641],{},[15,18642,4169],{},[4095,18644,4156],{},[4095,18646,4159],{},[4095,18648,4129],{},[4074,18650,18651,18655,18657,18659],{},[4095,18652,18653],{},[15,18654,4182],{},[4095,18656,4185],{},[4095,18658,4159],{},[4095,18660,4129],{},[4074,18662,18663,18667,18669,18671],{},[4095,18664,18665],{},[15,18666,4196],{},[4095,18668,4199],{},[4095,18670,4202],{},[4095,18672,4129],{},[83,18674,18675],{"className":85,"code":4207,"language":87,"meta":88,"style":88},[15,18676,18677,18701,18709,18717,18721,18753,18761,18769,18773,18777,18801],{"__ignoreMap":88},[92,18678,18679,18681,18683,18685,18687,18689,18691,18693,18695,18697,18699],{"class":94,"line":95},[92,18680,4214],{"class":119},[92,18682,126],{"class":98},[92,18684,347],{"class":119},[92,18686,1463],{"class":102},[92,18688,195],{"class":119},[92,18690,1448],{"class":102},[92,18692,195],{"class":119},[92,18694,3373],{"class":102},[92,18696,195],{"class":119},[92,18698,68],{"class":102},[92,18700,1034],{"class":119},[92,18702,18703,18705,18707],{"class":94,"line":106},[92,18704,4099],{"class":102},[92,18706,4241],{"class":119},[92,18708,4244],{"class":134},[92,18710,18711,18713,18715],{"class":94,"line":113},[92,18712,4103],{"class":102},[92,18714,4251],{"class":119},[92,18716,4254],{"class":134},[92,18718,18719],{"class":94,"line":138},[92,18720,110],{"emptyLinePlaceholder":109},[92,18722,18723,18725,18727,18729,18731,18733,18735,18737,18739,18741,18743,18745,18747,18749,18751],{"class":94,"line":143},[92,18724,4263],{"class":119},[92,18726,126],{"class":98},[92,18728,347],{"class":119},[92,18730,4270],{"class":171},[92,18732,1019],{"class":98},[92,18734,4275],{"class":102},[92,18736,195],{"class":119},[92,18738,4280],{"class":171},[92,18740,1019],{"class":98},[92,18742,4285],{"class":102},[92,18744,195],{"class":119},[92,18746,4290],{"class":171},[92,18748,1019],{"class":98},[92,18750,4295],{"class":102},[92,18752,1034],{"class":119},[92,18754,18755,18757,18759],{"class":94,"line":149},[92,18756,4119],{"class":102},[92,18758,4304],{"class":119},[92,18760,4307],{"class":134},[92,18762,18763,18765,18767],{"class":94,"line":155},[92,18764,4136],{"class":102},[92,18766,4304],{"class":119},[92,18768,4316],{"class":134},[92,18770,18771],{"class":94,"line":161},[92,18772,110],{"emptyLinePlaceholder":109},[92,18774,18775],{"class":94,"line":166},[92,18776,4325],{"class":134},[92,18778,18779,18781,18783,18785,18787,18789,18791,18793,18795,18797,18799],{"class":94,"line":187},[92,18780,4153],{"class":102},[92,18782,3786],{"class":119},[92,18784,3466],{"class":98},[92,18786,4336],{"class":119},[92,18788,2974],{"class":171},[92,18790,1751],{"class":119},[92,18792,1368],{"class":98},[92,18794,4345],{"class":119},[92,18796,2974],{"class":171},[92,18798,4350],{"class":119},[92,18800,4353],{"class":134},[92,18802,18803,18805,18807,18809,18811,18813,18815,18817,18819,18821,18823],{"class":94,"line":217},[92,18804,4153],{"class":102},[92,18806,3786],{"class":119},[92,18808,3466],{"class":98},[92,18810,4364],{"class":119},[92,18812,2974],{"class":171},[92,18814,1751],{"class":119},[92,18816,1368],{"class":98},[92,18818,4373],{"class":119},[92,18820,2974],{"class":171},[92,18822,4350],{"class":119},[92,18824,4380],{"class":134},[242,18826,4384],{"id":4383},[11,18828,4387,18829,4391,18831,4395,18833,4399,18835,4402],{},[15,18830,4390],{},[15,18832,4394],{},[1511,18834,4398],{},[15,18836,1807],{},[83,18838,18839],{"className":85,"code":4405,"language":87,"meta":88,"style":88},[15,18840,18841,18859,18875,18893,18903,18907,18921,18939,18959],{"__ignoreMap":88},[92,18842,18843,18845,18847,18849,18851,18853,18855,18857],{"class":94,"line":95},[92,18844,4412],{"class":119},[92,18846,126],{"class":98},[92,18848,347],{"class":119},[92,18850,4419],{"class":102},[92,18852,195],{"class":119},[92,18854,4424],{"class":102},[92,18856,4427],{"class":119},[92,18858,4430],{"class":134},[92,18860,18861,18863,18865,18867,18869,18871,18873],{"class":94,"line":106},[92,18862,1841],{"class":119},[92,18864,1016],{"class":171},[92,18866,1019],{"class":98},[92,18868,4441],{"class":119},[92,18870,126],{"class":98},[92,18872,4446],{"class":119},[92,18874,4449],{"class":134},[92,18876,18877,18879,18881,18883,18885,18887,18889,18891],{"class":94,"line":113},[92,18878,4454],{"class":119},[92,18880,126],{"class":98},[92,18882,347],{"class":119},[92,18884,68],{"class":102},[92,18886,195],{"class":119},[92,18888,354],{"class":102},[92,18890,4467],{"class":119},[92,18892,4470],{"class":134},[92,18894,18895,18897,18899,18901],{"class":94,"line":138},[92,18896,4475],{"class":119},[92,18898,126],{"class":98},[92,18900,4480],{"class":119},[92,18902,4483],{"class":134},[92,18904,18905],{"class":94,"line":143},[92,18906,110],{"emptyLinePlaceholder":109},[92,18908,18909,18911,18913,18915,18917,18919],{"class":94,"line":149},[92,18910,4394],{"class":98},[92,18912,4494],{"class":119},[92,18914,4497],{"class":98},[92,18916,4500],{"class":119},[92,18918,4503],{"class":134},[92,18920,4506],{"class":119},[92,18922,18923,18925,18927,18929,18931,18933,18935,18937],{"class":94,"line":155},[92,18924,4394],{"class":98},[92,18926,4513],{"class":119},[92,18928,4497],{"class":98},[92,18930,4518],{"class":119},[92,18932,4521],{"class":98},[92,18934,4500],{"class":119},[92,18936,4526],{"class":134},[92,18938,4506],{"class":119},[92,18940,18941,18943,18945,18947,18949,18951,18953,18955,18957],{"class":94,"line":161},[92,18942,4394],{"class":98},[92,18944,4494],{"class":119},[92,18946,4497],{"class":98},[92,18948,1895],{"class":98},[92,18950,4541],{"class":119},[92,18952,1188],{"class":98},[92,18954,1225],{"class":102},[92,18956,4548],{"class":119},[92,18958,4551],{"class":134},[92,18960,18961,18963,18965],{"class":94,"line":166},[92,18962,1131],{"class":102},[92,18964,4558],{"class":119},[92,18966,4561],{"class":134},[11,18968,4564,18969,4568,18971,4571,18973,4575],{},[15,18970,4567],{},[15,18972,3214],{},[15,18974,4574],{},[39,18976,4579],{"id":4578},[242,18978,4583],{"id":4582},[11,18980,18981,4100,18983,4100,18985,4595,18987,4599,18989,4603,18991,4607,18993,4611,18995,4615,18997,4618,18999,4621,19001,4625,19003,81],{},[15,18982,4588],{},[15,18984,4591],{},[15,18986,4594],{},[15,18988,4598],{},[15,18990,4602],{},[15,18992,4606],{},[1511,18994,4610],{},[15,18996,4614],{},[15,18998,17],{},[15,19000,4614],{},[15,19002,4624],{},[15,19004,4628],{},[83,19006,19007],{"className":85,"code":4631,"language":87,"meta":88,"style":88},[15,19008,19009,19021,19031,19045,19055,19063,19073,19077,19081,19085,19095,19115,19125,19135,19145,19149,19153,19157,19163,19171,19179,19189,19195,19201,19211],{"__ignoreMap":88},[92,19010,19011,19013,19015,19017,19019],{"class":94,"line":95},[92,19012,4588],{"class":98},[92,19014,4640],{"class":119},[92,19016,1599],{"class":98},[92,19018,331],{"class":102},[92,19020,4647],{"class":119},[92,19022,19023,19025,19027,19029],{"class":94,"line":106},[92,19024,4652],{"class":119},[92,19026,126],{"class":98},[92,19028,4657],{"class":171},[92,19030,229],{"class":119},[92,19032,19033,19035,19037,19039,19041,19043],{"class":94,"line":113},[92,19034,4664],{"class":119},[92,19036,4591],{"class":98},[92,19038,4640],{"class":119},[92,19040,4671],{"class":98},[92,19042,331],{"class":102},[92,19044,4647],{"class":119},[92,19046,19047,19049,19051,19053],{"class":94,"line":138},[92,19048,4652],{"class":119},[92,19050,126],{"class":98},[92,19052,4684],{"class":171},[92,19054,229],{"class":119},[92,19056,19057,19059,19061],{"class":94,"line":143},[92,19058,4664],{"class":119},[92,19060,4594],{"class":98},[92,19062,4695],{"class":119},[92,19064,19065,19067,19069,19071],{"class":94,"line":149},[92,19066,4652],{"class":119},[92,19068,126],{"class":98},[92,19070,4704],{"class":171},[92,19072,229],{"class":119},[92,19074,19075],{"class":94,"line":155},[92,19076,4711],{"class":119},[92,19078,19079],{"class":94,"line":161},[92,19080,110],{"emptyLinePlaceholder":109},[92,19082,19083],{"class":94,"line":166},[92,19084,4720],{"class":134},[92,19086,19087,19089,19091,19093],{"class":94,"line":187},[92,19088,4725],{"class":119},[92,19090,126],{"class":98},[92,19092,4730],{"class":98},[92,19094,4733],{"class":119},[92,19096,19097,19099,19101,19103,19105,19107,19109,19111,19113],{"class":94,"line":217},[92,19098,4738],{"class":102},[92,19100,195],{"class":119},[92,19102,4743],{"class":102},[92,19104,195],{"class":119},[92,19106,4748],{"class":102},[92,19108,1019],{"class":98},[92,19110,4753],{"class":171},[92,19112,3048],{"class":119},[92,19114,4758],{"class":134},[92,19116,19117,19119,19121,19123],{"class":94,"line":712},[92,19118,4763],{"class":102},[92,19120,4766],{"class":98},[92,19122,4769],{"class":171},[92,19124,4772],{"class":119},[92,19126,19127,19129,19131,19133],{"class":94,"line":730},[92,19128,4777],{"class":102},[92,19130,4766],{"class":98},[92,19132,4782],{"class":171},[92,19134,4772],{"class":119},[92,19136,19137,19139,19141,19143],{"class":94,"line":747},[92,19138,4789],{"class":98},[92,19140,4792],{"class":98},[92,19142,4795],{"class":171},[92,19144,4772],{"class":119},[92,19146,19147],{"class":94,"line":763},[92,19148,4802],{"class":119},[92,19150,19151],{"class":94,"line":780},[92,19152,110],{"emptyLinePlaceholder":109},[92,19154,19155],{"class":94,"line":785},[92,19156,4811],{"class":134},[92,19158,19159,19161],{"class":94,"line":2585},[92,19160,4606],{"class":98},[92,19162,4733],{"class":119},[92,19164,19165,19167,19169],{"class":94,"line":2605},[92,19166,4822],{"class":98},[92,19168,4825],{"class":102},[92,19170,4828],{"class":119},[92,19172,19173,19175,19177],{"class":94,"line":2634},[92,19174,4822],{"class":98},[92,19176,4835],{"class":102},[92,19178,4828],{"class":119},[92,19180,19181,19183,19185,19187],{"class":94,"line":2651},[92,19182,4842],{"class":119},[92,19184,126],{"class":98},[92,19186,4753],{"class":171},[92,19188,229],{"class":119},[92,19190,19191,19193],{"class":94,"line":2671},[92,19192,4853],{"class":98},[92,19194,229],{"class":119},[92,19196,19197,19199],{"class":94,"line":2676},[92,19198,4789],{"class":98},[92,19200,4828],{"class":119},[92,19202,19203,19205,19207,19209],{"class":94,"line":2697},[92,19204,4842],{"class":119},[92,19206,126],{"class":98},[92,19208,4795],{"class":171},[92,19210,229],{"class":119},[92,19212,19213],{"class":94,"line":2726},[92,19214,4711],{"class":119},[242,19216,4879],{"id":4878},[11,19218,4882,19219,4885,19221,4888,19223,4892,19225,4896],{},[15,19220,4394],{},[15,19222,4614],{},[15,19224,4891],{},[15,19226,4895],{},[83,19228,19229],{"className":85,"code":4899,"language":87,"meta":88,"style":88},[15,19230,19231,19257,19271,19275,19285,19301,19323,19327,19337,19347,19359,19369,19373,19385,19395,19399,19403],{"__ignoreMap":88},[92,19232,19233,19235,19237,19239,19241,19243,19245,19247,19249,19251,19253,19255],{"class":94,"line":95},[92,19234,4906],{"class":98},[92,19236,4909],{"class":119},[92,19238,126],{"class":98},[92,19240,331],{"class":102},[92,19242,4916],{"class":119},[92,19244,4671],{"class":98},[92,19246,1315],{"class":102},[92,19248,4923],{"class":119},[92,19250,4926],{"class":98},[92,19252,4929],{"class":119},[92,19254,4932],{"class":134},[92,19256,4506],{"class":119},[92,19258,19259,19261,19263,19265,19267,19269],{"class":94,"line":106},[92,19260,4394],{"class":98},[92,19262,4941],{"class":119},[92,19264,4497],{"class":98},[92,19266,4946],{"class":119},[92,19268,4932],{"class":134},[92,19270,4506],{"class":119},[92,19272,19273],{"class":94,"line":113},[92,19274,110],{"emptyLinePlaceholder":109},[92,19276,19277,19279,19281,19283],{"class":94,"line":138},[92,19278,4959],{"class":119},[92,19280,126],{"class":98},[92,19282,331],{"class":102},[92,19284,229],{"class":119},[92,19286,19287,19289,19291,19293,19295,19297,19299],{"class":94,"line":143},[92,19288,4970],{"class":98},[92,19290,4909],{"class":119},[92,19292,4671],{"class":98},[92,19294,1315],{"class":102},[92,19296,4979],{"class":119},[92,19298,4926],{"class":98},[92,19300,4984],{"class":119},[92,19302,19303,19305,19307,19309,19311,19313,19315,19317,19319,19321],{"class":94,"line":149},[92,19304,4989],{"class":98},[92,19306,4992],{"class":119},[92,19308,4995],{"class":98},[92,19310,4548],{"class":119},[92,19312,4970],{"class":98},[92,19314,4909],{"class":119},[92,19316,1599],{"class":98},[92,19318,331],{"class":102},[92,19320,131],{"class":119},[92,19322,5010],{"class":134},[92,19324,19325],{"class":94,"line":155},[92,19326,110],{"emptyLinePlaceholder":109},[92,19328,19329,19331,19333,19335],{"class":94,"line":161},[92,19330,4394],{"class":98},[92,19332,5021],{"class":119},[92,19334,4497],{"class":98},[92,19336,5026],{"class":119},[92,19338,19339,19341,19343,19345],{"class":94,"line":166},[92,19340,5031],{"class":98},[92,19342,5034],{"class":119},[92,19344,4497],{"class":98},[92,19346,5039],{"class":119},[92,19348,19349,19351,19353,19355,19357],{"class":94,"line":187},[92,19350,5044],{"class":98},[92,19352,5047],{"class":119},[92,19354,1352],{"class":98},[92,19356,1031],{"class":102},[92,19358,4647],{"class":119},[92,19360,19361,19363,19365,19367],{"class":94,"line":217},[92,19362,5058],{"class":98},[92,19364,1225],{"class":102},[92,19366,309],{"class":119},[92,19368,5065],{"class":134},[92,19370,19371],{"class":94,"line":712},[92,19372,5070],{"class":119},[92,19374,19375,19377,19379,19381,19383],{"class":94,"line":730},[92,19376,5044],{"class":98},[92,19378,5047],{"class":119},[92,19380,1352],{"class":98},[92,19382,5081],{"class":171},[92,19384,4647],{"class":119},[92,19386,19387,19389,19391,19393],{"class":94,"line":747},[92,19388,5088],{"class":98},[92,19390,1225],{"class":102},[92,19392,946],{"class":119},[92,19394,5095],{"class":134},[92,19396,19397],{"class":94,"line":763},[92,19398,5070],{"class":119},[92,19400,19401],{"class":94,"line":780},[92,19402,5104],{"class":119},[92,19404,19405],{"class":94,"line":785},[92,19406,4711],{"class":119},[11,19408,5111,19409,5114,19411,5117,19413,5121],{},[15,19410,17],{},[15,19412,4606],{},[15,19414,5120],{},[39,19416,5125],{"id":5124},[242,19418,5129],{"id":5128},[11,19420,5132,19421,5136,19423,5140,19425,195,19427,394,19429,81],{},[15,19422,5135],{},[15,19424,5139],{},[15,19426,5143],{},[15,19428,5146],{},[15,19430,5149],{},[83,19432,19433],{"className":85,"code":5152,"language":87,"meta":88,"style":88},[15,19434,19435,19463,19479,19483,19487,19499,19515,19539,19543,19563,19573],{"__ignoreMap":88},[92,19436,19437,19439,19441,19443,19445,19447,19449,19451,19453,19455,19457,19459,19461],{"class":94,"line":95},[92,19438,3556],{"class":98},[92,19440,5162],{"class":5161},[92,19442,120],{"class":119},[92,19444,376],{"class":98},[92,19446,5169],{"class":119},[92,19448,376],{"class":98},[92,19450,5174],{"class":119},[92,19452,126],{"class":98},[92,19454,5179],{"class":171},[92,19456,5182],{"class":119},[92,19458,5185],{"class":98},[92,19460,5188],{"class":98},[92,19462,4695],{"class":119},[92,19464,19465,19467,19469,19471,19473,19475,19477],{"class":94,"line":106},[92,19466,5195],{"class":98},[92,19468,5198],{"class":171},[92,19470,5201],{"class":119},[92,19472,195],{"class":171},[92,19474,2042],{"class":119},[92,19476,178],{"class":171},[92,19478,229],{"class":119},[92,19480,19481],{"class":94,"line":113},[92,19482,4711],{"class":119},[92,19484,19485],{"class":94,"line":138},[92,19486,110],{"emptyLinePlaceholder":109},[92,19488,19489,19491,19493,19495,19497],{"class":94,"line":143},[92,19490,5222],{"class":5161},[92,19492,120],{"class":119},[92,19494,5227],{"class":171},[92,19496,5230],{"class":119},[92,19498,5233],{"class":134},[92,19500,19501,19503,19505,19507,19509,19511,19513],{"class":94,"line":149},[92,19502,5222],{"class":5161},[92,19504,120],{"class":119},[92,19506,5227],{"class":171},[92,19508,195],{"class":119},[92,19510,5246],{"class":171},[92,19512,2645],{"class":119},[92,19514,5251],{"class":134},[92,19516,19517,19519,19521,19523,19525,19527,19529,19531,19533,19535,19537],{"class":94,"line":155},[92,19518,5222],{"class":5161},[92,19520,120],{"class":119},[92,19522,5260],{"class":5161},[92,19524,5263],{"class":119},[92,19526,5266],{"class":171},[92,19528,195],{"class":119},[92,19530,5271],{"class":5161},[92,19532,5263],{"class":119},[92,19534,5227],{"class":171},[92,19536,131],{"class":119},[92,19538,5280],{"class":134},[92,19540,19541],{"class":94,"line":161},[92,19542,110],{"emptyLinePlaceholder":109},[92,19544,19545,19547,19549,19551,19553,19555,19557,19559,19561],{"class":94,"line":166},[92,19546,3556],{"class":98},[92,19548,5291],{"class":5161},[92,19550,120],{"class":119},[92,19552,376],{"class":98},[92,19554,5298],{"class":119},[92,19556,5185],{"class":98},[92,19558,5303],{"class":98},[92,19560,5306],{"class":119},[92,19562,5309],{"class":134},[92,19564,19565,19567,19569,19571],{"class":94,"line":187},[92,19566,5314],{"class":102},[92,19568,5317],{"class":119},[92,19570,208],{"class":102},[92,19572,229],{"class":119},[92,19574,19575],{"class":94,"line":217},[92,19576,4711],{"class":119},[242,19578,5329],{"id":5328},[11,19580,5332,19581,5336,19583,5339,19585,5343],{},[15,19582,5335],{},[15,19584,5335],{},[15,19586,5342],{},[83,19588,19589],{"className":85,"code":5346,"language":87,"meta":88,"style":88},[15,19590,19591,19613,19621,19625,19645,19669,19673,19693],{"__ignoreMap":88},[92,19592,19593,19595,19597,19599,19601,19603,19605,19607,19609,19611],{"class":94,"line":95},[92,19594,3556],{"class":98},[92,19596,5355],{"class":5161},[92,19598,120],{"class":119},[92,19600,370],{"class":98},[92,19602,5362],{"class":98},[92,19604,5365],{"class":119},[92,19606,5185],{"class":98},[92,19608,5370],{"class":98},[92,19610,5306],{"class":119},[92,19612,5375],{"class":134},[92,19614,19615,19617,19619],{"class":94,"line":106},[92,19616,5195],{"class":98},[92,19618,5382],{"class":102},[92,19620,5385],{"class":119},[92,19622,19623],{"class":94,"line":113},[92,19624,4711],{"class":119},[92,19626,19627,19629,19631,19633,19635,19637,19639,19641,19643],{"class":94,"line":138},[92,19628,5394],{"class":5161},[92,19630,120],{"class":119},[92,19632,68],{"class":102},[92,19634,195],{"class":119},[92,19636,354],{"class":102},[92,19638,195],{"class":119},[92,19640,1448],{"class":102},[92,19642,571],{"class":119},[92,19644,5411],{"class":134},[92,19646,19647,19649,19651,19653,19655,19657,19659,19661,19663,19665,19667],{"class":94,"line":143},[92,19648,5394],{"class":5161},[92,19650,120],{"class":119},[92,19652,5335],{"class":98},[92,19654,1841],{"class":119},[92,19656,3621],{"class":102},[92,19658,195],{"class":119},[92,19660,1463],{"class":102},[92,19662,195],{"class":119},[92,19664,1235],{"class":102},[92,19666,3911],{"class":119},[92,19668,5436],{"class":134},[92,19670,19671],{"class":94,"line":149},[92,19672,110],{"emptyLinePlaceholder":109},[92,19674,19675,19677,19679,19681,19683,19685,19687,19689,19691],{"class":94,"line":155},[92,19676,5445],{"class":119},[92,19678,126],{"class":98},[92,19680,347],{"class":119},[92,19682,5452],{"class":171},[92,19684,195],{"class":119},[92,19686,5457],{"class":171},[92,19688,195],{"class":119},[92,19690,5462],{"class":171},[92,19692,1034],{"class":119},[92,19694,19695,19697,19699,19701,19703,19705,19707],{"class":94,"line":161},[92,19696,2729],{"class":102},[92,19698,120],{"class":119},[92,19700,5473],{"class":171},[92,19702,195],{"class":119},[92,19704,5335],{"class":98},[92,19706,5480],{"class":119},[92,19708,5483],{"class":134},[242,19710,5487],{"id":5486},[11,19712,5490,19713,5493,19715,834,19717,5499],{},[15,19714,1807],{},[15,19716,5496],{},[15,19718,3125],{},[83,19720,19721],{"className":85,"code":5502,"language":87,"meta":88,"style":88},[15,19722,19723,19747,19773,19777,19787,19795],{"__ignoreMap":88},[92,19724,19725,19727,19729,19731,19733,19735,19737,19739,19741,19743,19745],{"class":94,"line":95},[92,19726,3556],{"class":98},[92,19728,5511],{"class":5161},[92,19730,120],{"class":119},[92,19732,370],{"class":98},[92,19734,5518],{"class":119},[92,19736,5185],{"class":98},[92,19738,5303],{"class":98},[92,19740,5525],{"class":119},[92,19742,4926],{"class":98},[92,19744,5530],{"class":119},[92,19746,5533],{"class":134},[92,19748,19749,19751,19753,19755,19757,19759,19761,19763,19765,19767,19769,19771],{"class":94,"line":106},[92,19750,3556],{"class":98},[92,19752,5540],{"class":5161},[92,19754,120],{"class":119},[92,19756,370],{"class":98},[92,19758,1895],{"class":98},[92,19760,5549],{"class":119},[92,19762,5185],{"class":98},[92,19764,5303],{"class":98},[92,19766,5556],{"class":119},[92,19768,4926],{"class":98},[92,19770,5530],{"class":119},[92,19772,5563],{"class":134},[92,19774,19775],{"class":94,"line":113},[92,19776,110],{"emptyLinePlaceholder":109},[92,19778,19779,19781,19783,19785],{"class":94,"line":138},[92,19780,4214],{"class":119},[92,19782,126],{"class":98},[92,19784,1315],{"class":102},[92,19786,229],{"class":119},[92,19788,19789,19791,19793],{"class":94,"line":143},[92,19790,5582],{"class":5161},[92,19792,5585],{"class":119},[92,19794,5588],{"class":134},[92,19796,19797,19799,19801],{"class":94,"line":149},[92,19798,5593],{"class":5161},[92,19800,5585],{"class":119},[92,19802,5598],{"class":134},[242,19804,5602],{"id":5601},[11,19806,5605,19807,5609,19809,5613,19811,5617,19813,5621,19815,5624],{},[1511,19808,5608],{},[15,19810,5612],{},[1511,19812,5616],{},[15,19814,5620],{},[15,19816,3466],{},[83,19818,19819],{"className":85,"code":5627,"language":87,"meta":88,"style":88},[15,19820,19821,19831,19835,19839,19863,19875,19879,19883,19887,19915,19925,19929,19933,19937,19961,19965,19975,19985],{"__ignoreMap":88},[92,19822,19823,19825,19827,19829],{"class":94,"line":95},[92,19824,5634],{"class":119},[92,19826,126],{"class":98},[92,19828,856],{"class":102},[92,19830,229],{"class":119},[92,19832,19833],{"class":94,"line":106},[92,19834,110],{"emptyLinePlaceholder":109},[92,19836,19837],{"class":94,"line":113},[92,19838,5649],{"class":134},[92,19840,19841,19843,19845,19847,19849,19851,19853,19855,19857,19859,19861],{"class":94,"line":138},[92,19842,5654],{"class":119},[92,19844,126],{"class":98},[92,19846,5659],{"class":98},[92,19848,3559],{"class":119},[92,19850,370],{"class":98},[92,19852,5666],{"class":119},[92,19854,5612],{"class":98},[92,19856,5671],{"class":119},[92,19858,5185],{"class":98},[92,19860,5370],{"class":98},[92,19862,4695],{"class":119},[92,19864,19865,19867,19869,19871,19873],{"class":94,"line":143},[92,19866,5195],{"class":98},[92,19868,5684],{"class":119},[92,19870,1959],{"class":98},[92,19872,5689],{"class":119},[92,19874,5692],{"class":134},[92,19876,19877],{"class":94,"line":149},[92,19878,4802],{"class":119},[92,19880,19881],{"class":94,"line":155},[92,19882,110],{"emptyLinePlaceholder":109},[92,19884,19885],{"class":94,"line":161},[92,19886,5705],{"class":134},[92,19888,19889,19891,19893,19895,19897,19899,19901,19903,19905,19907,19909,19911,19913],{"class":94,"line":166},[92,19890,5710],{"class":119},[92,19892,126],{"class":98},[92,19894,5659],{"class":98},[92,19896,3559],{"class":119},[92,19898,370],{"class":98},[92,19900,5666],{"class":119},[92,19902,5612],{"class":98},[92,19904,3559],{"class":119},[92,19906,1807],{"class":98},[92,19908,5729],{"class":119},[92,19910,5185],{"class":98},[92,19912,5370],{"class":98},[92,19914,4695],{"class":119},[92,19916,19917,19919,19921,19923],{"class":94,"line":187},[92,19918,5195],{"class":98},[92,19920,5684],{"class":119},[92,19922,1959],{"class":98},[92,19924,5746],{"class":119},[92,19926,19927],{"class":94,"line":217},[92,19928,4802],{"class":119},[92,19930,19931],{"class":94,"line":712},[92,19932,110],{"emptyLinePlaceholder":109},[92,19934,19935],{"class":94,"line":730},[92,19936,5759],{"class":134},[92,19938,19939,19941,19943,19945,19947,19949,19951,19953,19955,19957,19959],{"class":94,"line":747},[92,19940,5764],{"class":119},[92,19942,126],{"class":98},[92,19944,5769],{"class":98},[92,19946,120],{"class":119},[92,19948,370],{"class":98},[92,19950,5776],{"class":119},[92,19952,5185],{"class":98},[92,19954,5370],{"class":98},[92,19956,5783],{"class":119},[92,19958,1959],{"class":98},[92,19960,5746],{"class":119},[92,19962,19963],{"class":94,"line":763},[92,19964,110],{"emptyLinePlaceholder":109},[92,19966,19967,19969,19971,19973],{"class":94,"line":780},[92,19968,5634],{"class":119},[92,19970,126],{"class":98},[92,19972,1286],{"class":102},[92,19974,229],{"class":119},[92,19976,19977,19979,19981,19983],{"class":94,"line":785},[92,19978,5806],{"class":119},[92,19980,354],{"class":102},[92,19982,800],{"class":119},[92,19984,5813],{"class":134},[92,19986,19987,19989,19991,19993],{"class":94,"line":2585},[92,19988,5818],{"class":119},[92,19990,354],{"class":102},[92,19992,2770],{"class":119},[92,19994,5825],{"class":134},[242,19996,5829],{"id":5828},[11,19998,5832,19999,5836,20001,5840,20003,5844,20005,5848],{},[15,20000,5835],{},[15,20002,5839],{},[15,20004,5843],{},[15,20006,5847],{},[83,20008,20009],{"className":85,"code":5851,"language":87,"meta":88,"style":88},[15,20010,20011,20031,20055],{"__ignoreMap":88},[92,20012,20013,20015,20017,20019,20021,20023,20025,20027,20029],{"class":94,"line":95},[92,20014,3322],{"class":102},[92,20016,120],{"class":119},[92,20018,5862],{"class":171},[92,20020,2708],{"class":119},[92,20022,1844],{"class":171},[92,20024,195],{"class":119},[92,20026,198],{"class":171},[92,20028,5873],{"class":119},[92,20030,5876],{"class":134},[92,20032,20033,20035,20037,20039,20041,20043,20045,20047,20049,20051,20053],{"class":94,"line":106},[92,20034,3322],{"class":102},[92,20036,120],{"class":119},[92,20038,2326],{"class":102},[92,20040,120],{"class":119},[92,20042,5335],{"class":98},[92,20044,5891],{"class":119},[92,20046,1844],{"class":171},[92,20048,195],{"class":119},[92,20050,198],{"class":171},[92,20052,5900],{"class":119},[92,20054,5903],{"class":134},[92,20056,20057,20059,20061,20063,20065],{"class":94,"line":113},[92,20058,4153],{"class":102},[92,20060,5910],{"class":119},[92,20062,5913],{"class":171},[92,20064,495],{"class":119},[92,20066,5918],{"class":134},[242,20068,5922],{"id":5921},[11,20070,5925,20071,5929,20073,5932],{},[15,20072,5928],{},[15,20074,5928],{},[83,20076,20077],{"className":85,"code":5935,"language":87,"meta":88,"style":88},[15,20078,20079,20097,20117,20125,20129,20133,20157,20161,20175,20189,20201],{"__ignoreMap":88},[92,20080,20081,20083,20085,20087,20089,20091,20093,20095],{"class":94,"line":95},[92,20082,3556],{"class":98},[92,20084,5944],{"class":5161},[92,20086,120],{"class":119},[92,20088,370],{"class":98},[92,20090,5951],{"class":119},[92,20092,5185],{"class":98},[92,20094,5956],{"class":102},[92,20096,4695],{"class":119},[92,20098,20099,20101,20103,20105,20107,20109,20111,20113,20115],{"class":94,"line":106},[92,20100,5963],{"class":98},[92,20102,4909],{"class":119},[92,20104,126],{"class":98},[92,20106,1849],{"class":102},[92,20108,4916],{"class":119},[92,20110,5974],{"class":98},[92,20112,5977],{"class":119},[92,20114,4926],{"class":98},[92,20116,4647],{"class":119},[92,20118,20119,20121,20123],{"class":94,"line":113},[92,20120,5986],{"class":98},[92,20122,5989],{"class":119},[92,20124,5992],{"class":134},[92,20126,20127],{"class":94,"line":138},[92,20128,5104],{"class":119},[92,20130,20131],{"class":94,"line":143},[92,20132,4711],{"class":119},[92,20134,20135,20137,20139,20141,20143,20145,20147,20149,20151,20153,20155],{"class":94,"line":149},[92,20136,4394],{"class":98},[92,20138,3559],{"class":119},[92,20140,6009],{"class":5161},[92,20142,120],{"class":119},[92,20144,1448],{"class":102},[92,20146,683],{"class":119},[92,20148,4497],{"class":98},[92,20150,6020],{"class":119},[92,20152,60],{"class":102},[92,20154,6025],{"class":119},[92,20156,6028],{"class":134},[92,20158,20159],{"class":94,"line":155},[92,20160,110],{"emptyLinePlaceholder":109},[92,20162,20163,20165,20167,20169,20171,20173],{"class":94,"line":161},[92,20164,3556],{"class":98},[92,20166,6039],{"class":5161},[92,20168,6042],{"class":119},[92,20170,5185],{"class":98},[92,20172,5956],{"class":102},[92,20174,4695],{"class":119},[92,20176,20177,20179,20181,20183,20185,20187],{"class":94,"line":166},[92,20178,6053],{"class":98},[92,20180,192],{"class":171},[92,20182,1019],{"class":98},[92,20184,1849],{"class":102},[92,20186,6062],{"class":119},[92,20188,6065],{"class":134},[92,20190,20191,20193,20195,20197,20199],{"class":94,"line":187},[92,20192,6053],{"class":98},[92,20194,3009],{"class":171},[92,20196,1019],{"class":98},[92,20198,1225],{"class":102},[92,20200,229],{"class":119},[92,20202,20203],{"class":94,"line":217},[92,20204,4711],{"class":119},[11,20206,1792,20207,6086,20209,6089],{},[15,20208,5612],{},[15,20210,5620],{},[39,20212,6093],{"id":6092},[242,20214,6097,20215],{"id":6096},[15,20216,6100],{},[11,20218,6103,20219,6106,20221,6109,20223,6112],{},[15,20220,3334],{},[15,20222,6100],{},[15,20224,1996],{},[83,20226,20227],{"className":85,"code":6115,"language":87,"meta":88,"style":88},[15,20228,20229,20237,20247,20255,20259,20277,20291,20303,20307,20311,20327,20345,20349,20353,20357,20377,20389],{"__ignoreMap":88},[92,20230,20231,20233,20235],{"class":94,"line":95},[92,20232,6122],{"class":98},[92,20234,6125],{"class":5161},[92,20236,4695],{"class":119},[92,20238,20239,20241,20243,20245],{"class":94,"line":106},[92,20240,6132],{"class":98},[92,20242,6135],{"class":98},[92,20244,6138],{"class":119},[92,20246,6141],{"class":134},[92,20248,20249,20251,20253],{"class":94,"line":113},[92,20250,6132],{"class":98},[92,20252,6135],{"class":98},[92,20254,6150],{"class":119},[92,20256,20257],{"class":94,"line":138},[92,20258,110],{"emptyLinePlaceholder":109},[92,20260,20261,20263,20265,20267,20269,20271,20273,20275],{"class":94,"line":143},[92,20262,6132],{"class":98},[92,20264,5659],{"class":98},[92,20266,6163],{"class":102},[92,20268,120],{"class":119},[92,20270,373],{"class":98},[92,20272,6170],{"class":119},[92,20274,373],{"class":98},[92,20276,6175],{"class":119},[92,20278,20279,20281,20283,20285,20287,20289],{"class":94,"line":149},[92,20280,6180],{"class":102},[92,20282,1996],{"class":98},[92,20284,6185],{"class":119},[92,20286,126],{"class":98},[92,20288,6190],{"class":119},[92,20290,6193],{"class":134},[92,20292,20293,20295,20297,20299,20301],{"class":94,"line":155},[92,20294,6180],{"class":102},[92,20296,1996],{"class":98},[92,20298,6202],{"class":119},[92,20300,126],{"class":98},[92,20302,6150],{"class":119},[92,20304,20305],{"class":94,"line":161},[92,20306,5104],{"class":119},[92,20308,20309],{"class":94,"line":166},[92,20310,110],{"emptyLinePlaceholder":109},[92,20312,20313,20315,20317,20319,20321,20323,20325],{"class":94,"line":187},[92,20314,6132],{"class":98},[92,20316,5659],{"class":98},[92,20318,6223],{"class":5161},[92,20320,6042],{"class":119},[92,20322,5185],{"class":98},[92,20324,6135],{"class":98},[92,20326,4695],{"class":119},[92,20328,20329,20331,20333,20335,20337,20339,20341,20343],{"class":94,"line":217},[92,20330,6236],{"class":98},[92,20332,6239],{"class":102},[92,20334,1996],{"class":98},[92,20336,6185],{"class":119},[92,20338,1959],{"class":98},[92,20340,6239],{"class":102},[92,20342,1996],{"class":98},[92,20344,6252],{"class":119},[92,20346,20347],{"class":94,"line":712},[92,20348,5104],{"class":119},[92,20350,20351],{"class":94,"line":730},[92,20352,4711],{"class":119},[92,20354,20355],{"class":94,"line":747},[92,20356,110],{"emptyLinePlaceholder":109},[92,20358,20359,20361,20363,20365,20367,20369,20371,20373,20375],{"class":94,"line":763},[92,20360,6269],{"class":119},[92,20362,126],{"class":98},[92,20364,6274],{"class":98},[92,20366,6125],{"class":102},[92,20368,120],{"class":119},[92,20370,6281],{"class":102},[92,20372,195],{"class":119},[92,20374,6286],{"class":102},[92,20376,6289],{"class":119},[92,20378,20379,20381,20383,20385,20387],{"class":94,"line":780},[92,20380,6294],{"class":119},[92,20382,1996],{"class":98},[92,20384,6299],{"class":5161},[92,20386,6302],{"class":119},[92,20388,6305],{"class":134},[92,20390,20391,20393,20395,20397],{"class":94,"line":785},[92,20392,6294],{"class":119},[92,20394,1996],{"class":98},[92,20396,6314],{"class":119},[92,20398,6317],{"class":134},[242,20400,6321],{"id":6320},[11,20402,6324,20403,6328,20405,6332,20407,6336,20409,6339,20411,6342],{},[15,20404,6327],{},[15,20406,6331],{},[15,20408,6335],{},[15,20410,6335],{},[15,20412,6331],{},[83,20414,20415],{"className":85,"code":6345,"language":87,"meta":88,"style":88},[15,20416,20417,20425,20441,20445,20465,20479,20483,20499,20511,20515],{"__ignoreMap":88},[92,20418,20419,20421,20423],{"class":94,"line":95},[92,20420,6122],{"class":98},[92,20422,6354],{"class":5161},[92,20424,4695],{"class":119},[92,20426,20427,20429,20431,20433,20435,20437,20439],{"class":94,"line":106},[92,20428,6361],{"class":98},[92,20430,6135],{"class":98},[92,20432,6366],{"class":119},[92,20434,126],{"class":98},[92,20436,6371],{"class":102},[92,20438,946],{"class":119},[92,20440,6376],{"class":134},[92,20442,20443],{"class":94,"line":113},[92,20444,110],{"emptyLinePlaceholder":109},[92,20446,20447,20449,20451,20453,20455,20457,20459,20461,20463],{"class":94,"line":138},[92,20448,6132],{"class":98},[92,20450,5659],{"class":98},[92,20452,6389],{"class":5161},[92,20454,120],{"class":119},[92,20456,373],{"class":98},[92,20458,6396],{"class":119},[92,20460,5185],{"class":98},[92,20462,5303],{"class":98},[92,20464,4695],{"class":119},[92,20466,20467,20469,20471,20473,20475,20477],{"class":94,"line":143},[92,20468,6180],{"class":102},[92,20470,1996],{"class":98},[92,20472,6411],{"class":119},[92,20474,1182],{"class":98},[92,20476,6416],{"class":119},[92,20478,6419],{"class":134},[92,20480,20481],{"class":94,"line":149},[92,20482,5104],{"class":119},[92,20484,20485,20487,20489,20491,20493,20495,20497],{"class":94,"line":155},[92,20486,6132],{"class":98},[92,20488,5659],{"class":98},[92,20490,6432],{"class":5161},[92,20492,6042],{"class":119},[92,20494,5185],{"class":98},[92,20496,6135],{"class":98},[92,20498,4695],{"class":119},[92,20500,20501,20503,20505,20507,20509],{"class":94,"line":161},[92,20502,6236],{"class":98},[92,20504,6239],{"class":102},[92,20506,1996],{"class":98},[92,20508,6451],{"class":119},[92,20510,6454],{"class":134},[92,20512,20513],{"class":94,"line":166},[92,20514,5104],{"class":119},[92,20516,20517],{"class":94,"line":187},[92,20518,4711],{"class":119},[242,20520,6466],{"id":6465},[11,20522,20523,6472,20525,394,20527,6478,20529,6482],{},[15,20524,6471],{},[15,20526,3334],{},[15,20528,6477],{},[1511,20530,6481],{},[83,20532,20533],{"className":85,"code":6485,"language":87,"meta":88,"style":88},[15,20534,20535,20539,20547,20555,20563,20581,20593,20605,20609,20613,20617,20621,20629,20639,20653,20667,20671,20675,20679,20699],{"__ignoreMap":88},[92,20536,20537],{"class":94,"line":95},[92,20538,6492],{"class":134},[92,20540,20541,20543,20545],{"class":94,"line":106},[92,20542,6122],{"class":98},[92,20544,6499],{"class":5161},[92,20546,4695],{"class":119},[92,20548,20549,20551,20553],{"class":94,"line":113},[92,20550,6132],{"class":98},[92,20552,5370],{"class":98},[92,20554,6510],{"class":119},[92,20556,20557,20559,20561],{"class":94,"line":138},[92,20558,6132],{"class":98},[92,20560,5370],{"class":98},[92,20562,6519],{"class":119},[92,20564,20565,20567,20569,20571,20573,20575,20577,20579],{"class":94,"line":143},[92,20566,6132],{"class":98},[92,20568,5659],{"class":98},[92,20570,6163],{"class":102},[92,20572,120],{"class":119},[92,20574,370],{"class":98},[92,20576,6534],{"class":119},[92,20578,370],{"class":98},[92,20580,6539],{"class":119},[92,20582,20583,20585,20587,20589,20591],{"class":94,"line":149},[92,20584,6180],{"class":102},[92,20586,1996],{"class":98},[92,20588,6548],{"class":119},[92,20590,126],{"class":98},[92,20592,6510],{"class":119},[92,20594,20595,20597,20599,20601,20603],{"class":94,"line":155},[92,20596,6180],{"class":102},[92,20598,1996],{"class":98},[92,20600,6561],{"class":119},[92,20602,126],{"class":98},[92,20604,6519],{"class":119},[92,20606,20607],{"class":94,"line":161},[92,20608,5104],{"class":119},[92,20610,20611],{"class":94,"line":166},[92,20612,4711],{"class":119},[92,20614,20615],{"class":94,"line":187},[92,20616,110],{"emptyLinePlaceholder":109},[92,20618,20619],{"class":94,"line":217},[92,20620,6582],{"class":134},[92,20622,20623,20625,20627],{"class":94,"line":712},[92,20624,6122],{"class":98},[92,20626,6589],{"class":5161},[92,20628,4695],{"class":119},[92,20630,20631,20633,20635,20637],{"class":94,"line":730},[92,20632,6132],{"class":98},[92,20634,5659],{"class":98},[92,20636,6163],{"class":102},[92,20638,6602],{"class":119},[92,20640,20641,20643,20645,20647,20649,20651],{"class":94,"line":747},[92,20642,6607],{"class":98},[92,20644,5370],{"class":98},[92,20646,6612],{"class":119},[92,20648,126],{"class":98},[92,20650,331],{"class":102},[92,20652,4772],{"class":119},[92,20654,20655,20657,20659,20661,20663,20665],{"class":94,"line":763},[92,20656,6607],{"class":98},[92,20658,5370],{"class":98},[92,20660,6627],{"class":119},[92,20662,126],{"class":98},[92,20664,331],{"class":102},[92,20666,4772],{"class":119},[92,20668,20669],{"class":94,"line":780},[92,20670,6638],{"class":119},[92,20672,20673],{"class":94,"line":785},[92,20674,4711],{"class":119},[92,20676,20677],{"class":94,"line":2585},[92,20678,110],{"emptyLinePlaceholder":109},[92,20680,20681,20683,20685,20687,20689,20691,20693,20695,20697],{"class":94,"line":2605},[92,20682,6651],{"class":119},[92,20684,126],{"class":98},[92,20686,6274],{"class":98},[92,20688,6589],{"class":102},[92,20690,120],{"class":119},[92,20692,354],{"class":102},[92,20694,195],{"class":119},[92,20696,1463],{"class":102},[92,20698,6289],{"class":119},[92,20700,20701,20703,20705,20707],{"class":94,"line":2634},[92,20702,6672],{"class":119},[92,20704,1996],{"class":98},[92,20706,6677],{"class":119},[92,20708,2582],{"class":134},[242,20710,6683],{"id":6682},[11,20712,6686,20713,6690],{},[15,20714,6689],{},[83,20716,20717],{"className":85,"code":6693,"language":87,"meta":88,"style":88},[15,20718,20719,20727,20737,20747,20763,20767,20771,20775,20791,20801],{"__ignoreMap":88},[92,20720,20721,20723,20725],{"class":94,"line":95},[92,20722,6122],{"class":98},[92,20724,6702],{"class":5161},[92,20726,4695],{"class":119},[92,20728,20729,20731,20733,20735],{"class":94,"line":106},[92,20730,6132],{"class":98},[92,20732,5659],{"class":98},[92,20734,6163],{"class":102},[92,20736,6602],{"class":119},[92,20738,20739,20741,20743,20745],{"class":94,"line":113},[92,20740,6607],{"class":98},[92,20742,6721],{"class":98},[92,20744,5370],{"class":98},[92,20746,6726],{"class":119},[92,20748,20749,20751,20753,20755,20757,20759,20761],{"class":94,"line":138},[92,20750,6607],{"class":98},[92,20752,6721],{"class":98},[92,20754,5188],{"class":98},[92,20756,6737],{"class":119},[92,20758,126],{"class":98},[92,20760,6742],{"class":171},[92,20762,4772],{"class":119},[92,20764,20765],{"class":94,"line":143},[92,20766,6638],{"class":119},[92,20768,20769],{"class":94,"line":149},[92,20770,4711],{"class":119},[92,20772,20773],{"class":94,"line":155},[92,20774,110],{"emptyLinePlaceholder":109},[92,20776,20777,20779,20781,20783,20785,20787,20789],{"class":94,"line":161},[92,20778,6761],{"class":119},[92,20780,126],{"class":98},[92,20782,6274],{"class":98},[92,20784,6702],{"class":102},[92,20786,120],{"class":119},[92,20788,6772],{"class":102},[92,20790,6289],{"class":119},[92,20792,20793,20795,20797,20799],{"class":94,"line":166},[92,20794,6779],{"class":119},[92,20796,1996],{"class":98},[92,20798,6784],{"class":119},[92,20800,6787],{"class":134},[92,20802,20803,20805,20807,20809,20811,20813,20815],{"class":94,"line":187},[92,20804,6779],{"class":119},[92,20806,1996],{"class":98},[92,20808,6796],{"class":119},[92,20810,126],{"class":98},[92,20812,6801],{"class":102},[92,20814,309],{"class":119},[92,20816,6806],{"class":134},[242,20818,6810],{"id":6809},[11,20820,6686,20821,6815,20823,6819,20825,6822,20827,6826,20829,6830],{},[15,20822,5146],{},[15,20824,6818],{},[15,20826,816],{},[15,20828,6825],{},[15,20830,6829],{},[83,20832,20833],{"className":85,"code":6833,"language":87,"meta":88,"style":88},[15,20834,20835,20843,20859,20877,20881,20899,20909,20913,20917,20921,20933,20945,20959],{"__ignoreMap":88},[92,20836,20837,20839,20841],{"class":94,"line":95},[92,20838,6122],{"class":98},[92,20840,6842],{"class":5161},[92,20842,4695],{"class":119},[92,20844,20845,20847,20849,20851,20853,20855,20857],{"class":94,"line":106},[92,20846,6132],{"class":98},[92,20848,6851],{"class":98},[92,20850,6854],{"class":102},[92,20852,853],{"class":98},[92,20854,331],{"class":102},[92,20856,6062],{"class":119},[92,20858,6863],{"class":134},[92,20860,20861,20863,20865,20867,20869,20871,20873,20875],{"class":94,"line":113},[92,20862,6361],{"class":98},[92,20864,6870],{"class":98},[92,20866,5370],{"class":98},[92,20868,6875],{"class":119},[92,20870,126],{"class":98},[92,20872,331],{"class":102},[92,20874,724],{"class":119},[92,20876,6884],{"class":134},[92,20878,20879],{"class":94,"line":138},[92,20880,110],{"emptyLinePlaceholder":109},[92,20882,20883,20885,20887,20889,20891,20893,20895,20897],{"class":94,"line":143},[92,20884,6132],{"class":98},[92,20886,6870],{"class":98},[92,20888,5659],{"class":98},[92,20890,6899],{"class":5161},[92,20892,6042],{"class":119},[92,20894,5185],{"class":98},[92,20896,5370],{"class":98},[92,20898,4695],{"class":119},[92,20900,20901,20903,20905,20907],{"class":94,"line":149},[92,20902,6236],{"class":98},[92,20904,6914],{"class":98},[92,20906,6917],{"class":119},[92,20908,6920],{"class":134},[92,20910,20911],{"class":94,"line":155},[92,20912,5104],{"class":119},[92,20914,20915],{"class":94,"line":161},[92,20916,4711],{"class":119},[92,20918,20919],{"class":94,"line":166},[92,20920,110],{"emptyLinePlaceholder":109},[92,20922,20923,20925,20927,20929,20931],{"class":94,"line":187},[92,20924,6937],{"class":102},[92,20926,6818],{"class":98},[92,20928,6942],{"class":5161},[92,20930,6945],{"class":119},[92,20932,6948],{"class":134},[92,20934,20935,20937,20939,20941,20943],{"class":94,"line":217},[92,20936,6937],{"class":102},[92,20938,6818],{"class":98},[92,20940,6942],{"class":5161},[92,20942,6945],{"class":119},[92,20944,2582],{"class":134},[92,20946,20947,20949,20951,20953,20955,20957],{"class":94,"line":712},[92,20948,60],{"class":102},[92,20950,6842],{"class":102},[92,20952,6818],{"class":98},[92,20954,6971],{"class":102},[92,20956,211],{"class":119},[92,20958,6976],{"class":134},[92,20960,20961,20963,20965,20967,20969],{"class":94,"line":730},[92,20962,60],{"class":102},[92,20964,6842],{"class":102},[92,20966,6985],{"class":98},[92,20968,211],{"class":119},[92,20970,6990],{"class":134},[242,20972,6994],{"id":6993},[11,20974,6997,20975,7001,20977,7005,20979,7009],{},[15,20976,7000],{},[15,20978,7004],{},[15,20980,7008],{},[83,20982,20983],{"className":85,"code":7012,"language":87,"meta":88,"style":88},[15,20984,20985,20993,21009,21025,21041,21045,21049,21053,21065,21083,21101,21105,21109,21113],{"__ignoreMap":88},[92,20986,20987,20989,20991],{"class":94,"line":95},[92,20988,6122],{"class":98},[92,20990,7021],{"class":5161},[92,20992,4695],{"class":119},[92,20994,20995,20997,20999,21001,21003,21005,21007],{"class":94,"line":106},[92,20996,6132],{"class":98},[92,20998,5659],{"class":98},[92,21000,6163],{"class":102},[92,21002,120],{"class":119},[92,21004,6331],{"class":98},[92,21006,5188],{"class":98},[92,21008,7040],{"class":119},[92,21010,21011,21013,21015,21017,21019,21021,21023],{"class":94,"line":113},[92,21012,6132],{"class":98},[92,21014,5659],{"class":98},[92,21016,7049],{"class":5161},[92,21018,6042],{"class":119},[92,21020,5185],{"class":98},[92,21022,5188],{"class":98},[92,21024,4695],{"class":119},[92,21026,21027,21029,21031,21033,21035,21037,21039],{"class":94,"line":138},[92,21028,6236],{"class":98},[92,21030,5198],{"class":171},[92,21032,6100],{"class":119},[92,21034,1996],{"class":98},[92,21036,5271],{"class":119},[92,21038,7072],{"class":171},[92,21040,229],{"class":119},[92,21042,21043],{"class":94,"line":143},[92,21044,5104],{"class":119},[92,21046,21047],{"class":94,"line":149},[92,21048,4711],{"class":119},[92,21050,21051],{"class":94,"line":155},[92,21052,110],{"emptyLinePlaceholder":109},[92,21054,21055,21057,21059,21061,21063],{"class":94,"line":161},[92,21056,6122],{"class":98},[92,21058,7093],{"class":5161},[92,21060,7096],{"class":98},[92,21062,7021],{"class":5161},[92,21064,4695],{"class":119},[92,21066,21067,21069,21071,21073,21075,21077,21079,21081],{"class":94,"line":166},[92,21068,6132],{"class":98},[92,21070,5659],{"class":98},[92,21072,7049],{"class":5161},[92,21074,6042],{"class":119},[92,21076,5185],{"class":98},[92,21078,5188],{"class":98},[92,21080,7117],{"class":119},[92,21082,7120],{"class":134},[92,21084,21085,21087,21089,21091,21093,21095,21097,21099],{"class":94,"line":187},[92,21086,6236],{"class":98},[92,21088,7127],{"class":98},[92,21090,7130],{"class":5161},[92,21092,7133],{"class":119},[92,21094,81],{"class":98},[92,21096,7138],{"class":171},[92,21098,2279],{"class":119},[92,21100,7143],{"class":134},[92,21102,21103],{"class":94,"line":217},[92,21104,5104],{"class":119},[92,21106,21107],{"class":94,"line":712},[92,21108,4711],{"class":119},[92,21110,21111],{"class":94,"line":730},[92,21112,110],{"emptyLinePlaceholder":109},[92,21114,21115,21117,21119,21121,21123,21125,21127,21129,21131,21133],{"class":94,"line":747},[92,21116,120],{"class":119},[92,21118,3334],{"class":98},[92,21120,7093],{"class":102},[92,21122,120],{"class":119},[92,21124,7168],{"class":171},[92,21126,7171],{"class":119},[92,21128,1996],{"class":98},[92,21130,7130],{"class":5161},[92,21132,7178],{"class":119},[92,21134,7181],{"class":134},[242,21136,7185],{"id":7184},[11,21138,7188,21139,7192],{},[1511,21140,7191],{},[83,21142,21143],{"className":85,"code":7195,"language":87,"meta":88,"style":88},[15,21144,21145,21155,21175,21179,21197,21221,21225,21229,21233,21245,21261,21277,21299,21303,21307,21311,21315],{"__ignoreMap":88},[92,21146,21147,21149,21151,21153],{"class":94,"line":95},[92,21148,7191],{"class":98},[92,21150,7204],{"class":98},[92,21152,7207],{"class":5161},[92,21154,4695],{"class":119},[92,21156,21157,21159,21161,21163,21165,21167,21169,21171,21173],{"class":94,"line":106},[92,21158,7214],{"class":98},[92,21160,7217],{"class":98},[92,21162,5659],{"class":98},[92,21164,6223],{"class":5161},[92,21166,6042],{"class":119},[92,21168,5185],{"class":98},[92,21170,6135],{"class":98},[92,21172,211],{"class":119},[92,21174,7232],{"class":134},[92,21176,21177],{"class":94,"line":113},[92,21178,110],{"emptyLinePlaceholder":109},[92,21180,21181,21183,21185,21187,21189,21191,21193,21195],{"class":94,"line":138},[92,21182,6132],{"class":98},[92,21184,5659],{"class":98},[92,21186,7245],{"class":5161},[92,21188,6042],{"class":119},[92,21190,5185],{"class":98},[92,21192,5188],{"class":98},[92,21194,7254],{"class":119},[92,21196,7257],{"class":134},[92,21198,21199,21201,21203,21205,21207,21209,21211,21213,21215,21217,21219],{"class":94,"line":143},[92,21200,6236],{"class":98},[92,21202,7264],{"class":171},[92,21204,2108],{"class":98},[92,21206,7269],{"class":102},[92,21208,120],{"class":119},[92,21210,6100],{"class":102},[92,21212,1996],{"class":98},[92,21214,6299],{"class":5161},[92,21216,7280],{"class":119},[92,21218,354],{"class":102},[92,21220,6289],{"class":119},[92,21222,21223],{"class":94,"line":149},[92,21224,5104],{"class":119},[92,21226,21227],{"class":94,"line":155},[92,21228,4711],{"class":119},[92,21230,21231],{"class":94,"line":161},[92,21232,110],{"emptyLinePlaceholder":109},[92,21234,21235,21237,21239,21241,21243],{"class":94,"line":166},[92,21236,6122],{"class":98},[92,21238,7303],{"class":5161},[92,21240,7096],{"class":98},[92,21242,7207],{"class":5161},[92,21244,4695],{"class":119},[92,21246,21247,21249,21251,21253,21255,21257,21259],{"class":94,"line":187},[92,21248,6132],{"class":98},[92,21250,5659],{"class":98},[92,21252,6163],{"class":102},[92,21254,120],{"class":119},[92,21256,6335],{"class":98},[92,21258,6135],{"class":98},[92,21260,7326],{"class":119},[92,21262,21263,21265,21267,21269,21271,21273,21275],{"class":94,"line":217},[92,21264,6132],{"class":98},[92,21266,5659],{"class":98},[92,21268,6223],{"class":5161},[92,21270,6042],{"class":119},[92,21272,5185],{"class":98},[92,21274,6135],{"class":98},[92,21276,4695],{"class":119},[92,21278,21279,21281,21283,21285,21287,21289,21291,21293,21295,21297],{"class":94,"line":712},[92,21280,6236],{"class":98},[92,21282,7349],{"class":102},[92,21284,7352],{"class":98},[92,21286,6239],{"class":102},[92,21288,1996],{"class":98},[92,21290,7359],{"class":119},[92,21292,1165],{"class":98},[92,21294,1225],{"class":102},[92,21296,1572],{"class":119},[92,21298,7368],{"class":134},[92,21300,21301],{"class":94,"line":730},[92,21302,5104],{"class":119},[92,21304,21305],{"class":94,"line":747},[92,21306,4711],{"class":119},[92,21308,21309],{"class":94,"line":763},[92,21310,110],{"emptyLinePlaceholder":109},[92,21312,21313],{"class":94,"line":780},[92,21314,7385],{"class":134},[92,21316,21317,21319,21321,21323,21325,21327,21329,21331,21333,21335],{"class":94,"line":785},[92,21318,120],{"class":119},[92,21320,3334],{"class":98},[92,21322,7303],{"class":102},[92,21324,120],{"class":119},[92,21326,354],{"class":102},[92,21328,7171],{"class":119},[92,21330,1996],{"class":98},[92,21332,7404],{"class":5161},[92,21334,7178],{"class":119},[92,21336,7409],{"class":134},[242,21338,7413],{"id":7412},[11,21340,7416,21341,7420,21343,7424],{},[15,21342,7419],{},[1511,21344,7423],{},[83,21346,21347],{"className":85,"code":7427,"language":87,"meta":88,"style":88},[15,21348,21349,21357,21379,21383,21387,21395,21411,21415,21419,21423,21439,21455,21459,21479,21497,21501,21517,21533,21537],{"__ignoreMap":88},[92,21350,21351,21353,21355],{"class":94,"line":95},[92,21352,7434],{"class":98},[92,21354,7437],{"class":5161},[92,21356,4695],{"class":119},[92,21358,21359,21361,21363,21365,21367,21369,21371,21373,21375,21377],{"class":94,"line":106},[92,21360,6132],{"class":98},[92,21362,5659],{"class":98},[92,21364,7448],{"class":5161},[92,21366,120],{"class":119},[92,21368,5143],{"class":98},[92,21370,7455],{"class":119},[92,21372,5185],{"class":98},[92,21374,5370],{"class":98},[92,21376,309],{"class":119},[92,21378,7464],{"class":134},[92,21380,21381],{"class":94,"line":113},[92,21382,4711],{"class":119},[92,21384,21385],{"class":94,"line":138},[92,21386,110],{"emptyLinePlaceholder":109},[92,21388,21389,21391,21393],{"class":94,"line":143},[92,21390,7434],{"class":98},[92,21392,7479],{"class":5161},[92,21394,4695],{"class":119},[92,21396,21397,21399,21401,21403,21405,21407,21409],{"class":94,"line":149},[92,21398,6132],{"class":98},[92,21400,5659],{"class":98},[92,21402,7490],{"class":5161},[92,21404,6042],{"class":119},[92,21406,5185],{"class":98},[92,21408,7497],{"class":98},[92,21410,229],{"class":119},[92,21412,21413],{"class":94,"line":155},[92,21414,4711],{"class":119},[92,21416,21417],{"class":94,"line":161},[92,21418,110],{"emptyLinePlaceholder":109},[92,21420,21421],{"class":94,"line":166},[92,21422,7512],{"class":134},[92,21424,21425,21427,21429,21431,21433,21435,21437],{"class":94,"line":187},[92,21426,6122],{"class":98},[92,21428,7519],{"class":5161},[92,21430,7522],{"class":98},[92,21432,7437],{"class":5161},[92,21434,195],{"class":119},[92,21436,7529],{"class":102},[92,21438,4695],{"class":119},[92,21440,21441,21443,21445,21447,21449,21451,21453],{"class":94,"line":217},[92,21442,6132],{"class":98},[92,21444,5659],{"class":98},[92,21446,6163],{"class":102},[92,21448,120],{"class":119},[92,21450,6335],{"class":98},[92,21452,5370],{"class":98},[92,21454,7548],{"class":119},[92,21456,21457],{"class":94,"line":712},[92,21458,110],{"emptyLinePlaceholder":109},[92,21460,21461,21463,21465,21467,21469,21471,21473,21475,21477],{"class":94,"line":730},[92,21462,6132],{"class":98},[92,21464,5659],{"class":98},[92,21466,7448],{"class":5161},[92,21468,120],{"class":119},[92,21470,5143],{"class":98},[92,21472,7455],{"class":119},[92,21474,5185],{"class":98},[92,21476,5370],{"class":98},[92,21478,4695],{"class":119},[92,21480,21481,21483,21485,21487,21489,21491,21493,21495],{"class":94,"line":747},[92,21482,6236],{"class":98},[92,21484,6239],{"class":102},[92,21486,1996],{"class":98},[92,21488,7583],{"class":119},[92,21490,1368],{"class":98},[92,21492,7588],{"class":119},[92,21494,1996],{"class":98},[92,21496,7593],{"class":119},[92,21498,21499],{"class":94,"line":763},[92,21500,5104],{"class":119},[92,21502,21503,21505,21507,21509,21511,21513,21515],{"class":94,"line":780},[92,21504,6132],{"class":98},[92,21506,5659],{"class":98},[92,21508,7490],{"class":5161},[92,21510,6042],{"class":119},[92,21512,5185],{"class":98},[92,21514,7497],{"class":98},[92,21516,4695],{"class":119},[92,21518,21519,21521,21523,21525,21527,21529,21531],{"class":94,"line":785},[92,21520,6236],{"class":98},[92,21522,347],{"class":119},[92,21524,7622],{"class":171},[92,21526,1019],{"class":98},[92,21528,6239],{"class":102},[92,21530,1996],{"class":98},[92,21532,7631],{"class":119},[92,21534,21535],{"class":94,"line":2585},[92,21536,5104],{"class":119},[92,21538,21539],{"class":94,"line":2605},[92,21540,4711],{"class":119},[11,21542,7642,21543,7646,21545,7650],{},[1511,21544,7645],{},[1511,21546,7649],{},[242,21548,7654],{"id":7653},[11,21550,7657,21551,7660,21553,834,21555,81],{},[15,21552,5612],{},[15,21554,7663],{},[15,21556,4497],{},[83,21558,21559],{"className":85,"code":7668,"language":87,"meta":88,"style":88},[15,21560,21561,21569,21583,21599,21613,21617,21621,21625,21633,21641,21657,21671,21675,21679,21683,21691,21705,21721,21725,21729,21745,21755],{"__ignoreMap":88},[92,21562,21563,21565,21567],{"class":94,"line":95},[92,21564,7675],{"class":98},[92,21566,7678],{"class":5161},[92,21568,4695],{"class":119},[92,21570,21571,21573,21575,21577,21579,21581],{"class":94,"line":106},[92,21572,6132],{"class":98},[92,21574,7687],{"class":98},[92,21576,7690],{"class":119},[92,21578,126],{"class":98},[92,21580,1031],{"class":102},[92,21582,229],{"class":119},[92,21584,21585,21587,21589,21591,21593,21595,21597],{"class":94,"line":113},[92,21586,6132],{"class":98},[92,21588,5659],{"class":98},[92,21590,7705],{"class":5161},[92,21592,6042],{"class":119},[92,21594,5185],{"class":98},[92,21596,5303],{"class":98},[92,21598,4695],{"class":119},[92,21600,21601,21603,21605,21607,21609,21611],{"class":94,"line":138},[92,21602,6180],{"class":102},[92,21604,1996],{"class":98},[92,21606,7722],{"class":119},[92,21608,126],{"class":98},[92,21610,7727],{"class":102},[92,21612,7730],{"class":119},[92,21614,21615],{"class":94,"line":143},[92,21616,5104],{"class":119},[92,21618,21619],{"class":94,"line":149},[92,21620,4711],{"class":119},[92,21622,21623],{"class":94,"line":155},[92,21624,110],{"emptyLinePlaceholder":109},[92,21626,21627,21629,21631],{"class":94,"line":161},[92,21628,7675],{"class":98},[92,21630,7749],{"class":5161},[92,21632,4695],{"class":119},[92,21634,21635,21637,21639],{"class":94,"line":166},[92,21636,6132],{"class":98},[92,21638,5188],{"class":98},[92,21640,7760],{"class":119},[92,21642,21643,21645,21647,21649,21651,21653,21655],{"class":94,"line":187},[92,21644,6132],{"class":98},[92,21646,5659],{"class":98},[92,21648,7769],{"class":5161},[92,21650,6042],{"class":119},[92,21652,5185],{"class":98},[92,21654,5303],{"class":98},[92,21656,4695],{"class":119},[92,21658,21659,21661,21663,21665,21667,21669],{"class":94,"line":217},[92,21660,6180],{"class":102},[92,21662,1996],{"class":98},[92,21664,7786],{"class":119},[92,21666,126],{"class":98},[92,21668,7791],{"class":102},[92,21670,7730],{"class":119},[92,21672,21673],{"class":94,"line":712},[92,21674,5104],{"class":119},[92,21676,21677],{"class":94,"line":730},[92,21678,4711],{"class":119},[92,21680,21681],{"class":94,"line":747},[92,21682,110],{"emptyLinePlaceholder":109},[92,21684,21685,21687,21689],{"class":94,"line":763},[92,21686,6122],{"class":98},[92,21688,7812],{"class":5161},[92,21690,4695],{"class":119},[92,21692,21693,21695,21697,21699,21701,21703],{"class":94,"line":780},[92,21694,7819],{"class":98},[92,21696,7678],{"class":102},[92,21698,195],{"class":119},[92,21700,7826],{"class":102},[92,21702,309],{"class":119},[92,21704,7831],{"class":134},[92,21706,21707,21709,21711,21713,21715,21717,21719],{"class":94,"line":785},[92,21708,6132],{"class":98},[92,21710,5659],{"class":98},[92,21712,6163],{"class":102},[92,21714,120],{"class":119},[92,21716,6327],{"class":98},[92,21718,5188],{"class":98},[92,21720,7848],{"class":119},[92,21722,21723],{"class":94,"line":2585},[92,21724,4711],{"class":119},[92,21726,21727],{"class":94,"line":2605},[92,21728,110],{"emptyLinePlaceholder":109},[92,21730,21731,21733,21735,21737,21739,21741,21743],{"class":94,"line":2634},[92,21732,321],{"class":119},[92,21734,126],{"class":98},[92,21736,6274],{"class":98},[92,21738,7812],{"class":102},[92,21740,120],{"class":119},[92,21742,7871],{"class":171},[92,21744,6289],{"class":119},[92,21746,21747,21749,21751,21753],{"class":94,"line":2651},[92,21748,7878],{"class":119},[92,21750,1996],{"class":98},[92,21752,7883],{"class":5161},[92,21754,7730],{"class":119},[92,21756,21757,21759,21761,21763,21765],{"class":94,"line":2671},[92,21758,7878],{"class":119},[92,21760,1996],{"class":98},[92,21762,7894],{"class":5161},[92,21764,7178],{"class":119},[92,21766,7899],{"class":134},[242,21768,7903],{"id":7902},[11,21770,7906,21771,7910,21773,7914,21775,6339,21777,7919,21779,7923,21781,7927,21783,7930],{},[1511,21772,7909],{},[1511,21774,7913],{},[15,21776,376],{},[15,21778,370],{},[15,21780,7922],{},[15,21782,7926],{},[15,21784,390],{},[83,21786,21787],{"className":85,"code":7933,"language":87,"meta":88,"style":88},[15,21788,21789,21793,21801,21809,21817,21821,21833,21837,21841,21853,21865,21877,21881,21899,21913,21917,21921,21925,21939,21955,21971,21987],{"__ignoreMap":88},[92,21790,21791],{"class":94,"line":95},[92,21792,7940],{"class":134},[92,21794,21795,21797,21799],{"class":94,"line":106},[92,21796,7945],{"class":98},[92,21798,7948],{"class":5161},[92,21800,4695],{"class":119},[92,21802,21803,21805,21807],{"class":94,"line":113},[92,21804,4822],{"class":98},[92,21806,7957],{"class":102},[92,21808,229],{"class":119},[92,21810,21811,21813,21815],{"class":94,"line":138},[92,21812,4822],{"class":98},[92,21814,7966],{"class":102},[92,21816,229],{"class":119},[92,21818,21819],{"class":94,"line":143},[92,21820,4711],{"class":119},[92,21822,21823,21825,21827,21829,21831],{"class":94,"line":149},[92,21824,4085],{"class":102},[92,21826,6818],{"class":98},[92,21828,7981],{"class":102},[92,21830,7984],{"class":119},[92,21832,7987],{"class":134},[92,21834,21835],{"class":94,"line":155},[92,21836,110],{"emptyLinePlaceholder":109},[92,21838,21839],{"class":94,"line":161},[92,21840,7996],{"class":134},[92,21842,21843,21845,21847,21849,21851],{"class":94,"line":166},[92,21844,7945],{"class":98},[92,21846,8003],{"class":5161},[92,21848,5185],{"class":98},[92,21850,5188],{"class":98},[92,21852,4695],{"class":119},[92,21854,21855,21857,21859,21861,21863],{"class":94,"line":187},[92,21856,4822],{"class":98},[92,21858,8016],{"class":102},[92,21860,8019],{"class":98},[92,21862,8022],{"class":171},[92,21864,229],{"class":119},[92,21866,21867,21869,21871,21873,21875],{"class":94,"line":217},[92,21868,4822],{"class":98},[92,21870,8031],{"class":102},[92,21872,853],{"class":98},[92,21874,8036],{"class":171},[92,21876,229],{"class":119},[92,21878,21879],{"class":94,"line":712},[92,21880,110],{"emptyLinePlaceholder":109},[92,21882,21883,21885,21887,21889,21891,21893,21895,21897],{"class":94,"line":730},[92,21884,6132],{"class":98},[92,21886,5659],{"class":98},[92,21888,8051],{"class":5161},[92,21890,6042],{"class":119},[92,21892,5185],{"class":98},[92,21894,5188],{"class":98},[92,21896,8060],{"class":119},[92,21898,8063],{"class":134},[92,21900,21901,21903,21905,21907,21909,21911],{"class":94,"line":747},[92,21902,6236],{"class":98},[92,21904,8070],{"class":102},[92,21906,120],{"class":119},[92,21908,6100],{"class":102},[92,21910,1996],{"class":98},[92,21912,8079],{"class":119},[92,21914,21915],{"class":94,"line":763},[92,21916,5104],{"class":119},[92,21918,21919],{"class":94,"line":780},[92,21920,4711],{"class":119},[92,21922,21923],{"class":94,"line":785},[92,21924,110],{"emptyLinePlaceholder":109},[92,21926,21927,21929,21931,21933,21935,21937],{"class":94,"line":2585},[92,21928,8096],{"class":102},[92,21930,6818],{"class":98},[92,21932,8101],{"class":102},[92,21934,1996],{"class":98},[92,21936,8106],{"class":119},[92,21938,8109],{"class":134},[92,21940,21941,21943,21945,21947,21949,21951,21953],{"class":94,"line":2605},[92,21942,8096],{"class":102},[92,21944,6818],{"class":98},[92,21946,8101],{"class":102},[92,21948,1996],{"class":98},[92,21950,8122],{"class":5161},[92,21952,8125],{"class":119},[92,21954,8128],{"class":134},[92,21956,21957,21959,21961,21963,21965,21967,21969],{"class":94,"line":2634},[92,21958,8096],{"class":102},[92,21960,6818],{"class":98},[92,21962,8137],{"class":5161},[92,21964,120],{"class":119},[92,21966,8142],{"class":171},[92,21968,131],{"class":119},[92,21970,8147],{"class":134},[92,21972,21973,21975,21977,21979,21981,21983,21985],{"class":94,"line":2651},[92,21974,8096],{"class":102},[92,21976,6818],{"class":98},[92,21978,8156],{"class":5161},[92,21980,120],{"class":119},[92,21982,8161],{"class":171},[92,21984,2770],{"class":119},[92,21986,8166],{"class":134},[92,21988,21989,21991,21993,21995,21997],{"class":94,"line":2671},[92,21990,8096],{"class":102},[92,21992,6818],{"class":98},[92,21994,8175],{"class":5161},[92,21996,8178],{"class":119},[92,21998,8181],{"class":134},[242,22000,8185],{"id":8184},[11,22002,8188,22003,8192,22005,529,22007,8197,22009,8201,22011,529,22013,8208,22015,529,22017,8215,22019,8218,22021,8222],{},[15,22004,8191],{},[15,22006,6471],{},[15,22008,6477],{},[15,22010,8200],{},[15,22012,8204],{},[15,22014,8207],{},[15,22016,8211],{},[15,22018,8214],{},[15,22020,5839],{},[15,22022,8221],{},[83,22024,22025],{"className":85,"code":8225,"language":87,"meta":88,"style":88},[15,22026,22027,22035,22051,22055,22073,22101,22105,22109,22125,22129,22137,22153,22175,22189,22193,22197,22213,22223],{"__ignoreMap":88},[92,22028,22029,22031,22033],{"class":94,"line":95},[92,22030,6122],{"class":98},[92,22032,6702],{"class":5161},[92,22034,4695],{"class":119},[92,22036,22037,22039,22041,22043,22045,22047,22049],{"class":94,"line":106},[92,22038,6132],{"class":98},[92,22040,5659],{"class":98},[92,22042,6163],{"class":102},[92,22044,120],{"class":119},[92,22046,6335],{"class":98},[92,22048,5370],{"class":98},[92,22050,8252],{"class":119},[92,22052,22053],{"class":94,"line":113},[92,22054,110],{"emptyLinePlaceholder":109},[92,22056,22057,22059,22061,22063,22065,22067,22069,22071],{"class":94,"line":138},[92,22058,6132],{"class":98},[92,22060,5659],{"class":98},[92,22062,8265],{"class":102},[92,22064,6042],{"class":119},[92,22066,5185],{"class":98},[92,22068,5188],{"class":98},[92,22070,7117],{"class":119},[92,22072,8276],{"class":134},[92,22074,22075,22077,22079,22081,22083,22085,22087,22089,22091,22093,22095,22097,22099],{"class":94,"line":143},[92,22076,6236],{"class":98},[92,22078,8283],{"class":171},[92,22080,2108],{"class":98},[92,22082,8288],{"class":102},[92,22084,120],{"class":119},[92,22086,6100],{"class":102},[92,22088,1996],{"class":98},[92,22090,8297],{"class":119},[92,22092,529],{"class":98},[92,22094,8302],{"class":102},[92,22096,195],{"class":119},[92,22098,354],{"class":102},[92,22100,6289],{"class":119},[92,22102,22103],{"class":94,"line":149},[92,22104,5104],{"class":119},[92,22106,22107],{"class":94,"line":155},[92,22108,4711],{"class":119},[92,22110,22111,22113,22115,22117,22119,22121,22123],{"class":94,"line":161},[92,22112,60],{"class":102},[92,22114,6274],{"class":98},[92,22116,6702],{"class":102},[92,22118,120],{"class":119},[92,22120,8329],{"class":102},[92,22122,131],{"class":119},[92,22124,8334],{"class":134},[92,22126,22127],{"class":94,"line":166},[92,22128,110],{"emptyLinePlaceholder":109},[92,22130,22131,22133,22135],{"class":94,"line":187},[92,22132,6122],{"class":98},[92,22134,8345],{"class":5161},[92,22136,4695],{"class":119},[92,22138,22139,22141,22143,22145,22147,22149,22151],{"class":94,"line":217},[92,22140,6132],{"class":98},[92,22142,5659],{"class":98},[92,22144,6163],{"class":102},[92,22146,120],{"class":119},[92,22148,6335],{"class":98},[92,22150,5370],{"class":98},[92,22152,8364],{"class":119},[92,22154,22155,22157,22159,22161,22163,22165,22167,22169,22171,22173],{"class":94,"line":712},[92,22156,6132],{"class":98},[92,22158,5659],{"class":98},[92,22160,8373],{"class":102},[92,22162,120],{"class":119},[92,22164,370],{"class":98},[92,22166,5776],{"class":119},[92,22168,5185],{"class":98},[92,22170,5370],{"class":98},[92,22172,7117],{"class":119},[92,22174,8388],{"class":134},[92,22176,22177,22179,22181,22183,22185,22187],{"class":94,"line":730},[92,22178,6236],{"class":98},[92,22180,5684],{"class":119},[92,22182,1959],{"class":98},[92,22184,6239],{"class":102},[92,22186,1996],{"class":98},[92,22188,8403],{"class":119},[92,22190,22191],{"class":94,"line":747},[92,22192,5104],{"class":119},[92,22194,22195],{"class":94,"line":763},[92,22196,4711],{"class":119},[92,22198,22199,22201,22203,22205,22207,22209,22211],{"class":94,"line":780},[92,22200,8416],{"class":119},[92,22202,126],{"class":98},[92,22204,6274],{"class":98},[92,22206,8345],{"class":102},[92,22208,120],{"class":119},[92,22210,354],{"class":102},[92,22212,6289],{"class":119},[92,22214,22215,22217,22219,22221],{"class":94,"line":785},[92,22216,8433],{"class":119},[92,22218,1463],{"class":102},[92,22220,3995],{"class":119},[92,22222,8440],{"class":134},[92,22224,22225,22227,22229,22231,22233,22235,22237,22239,22241],{"class":94,"line":2585},[92,22226,3322],{"class":102},[92,22228,8447],{"class":119},[92,22230,68],{"class":102},[92,22232,195],{"class":119},[92,22234,354],{"class":102},[92,22236,195],{"class":119},[92,22238,1448],{"class":102},[92,22240,5873],{"class":119},[92,22242,8462],{"class":134},[242,22244,8466],{"id":8465},[11,22246,8469,22247,8472,22249,8475,22251,8479,22253,8483,22255,8486],{},[15,22248,1344],{},[15,22250,1352],{},[1511,22252,8478],{},[15,22254,8482],{},[15,22256,8221],{},[83,22258,22259],{"className":85,"code":8489,"language":87,"meta":88,"style":88},[15,22260,22261,22281,22291,22303,22307,22317,22327,22337,22341,22355],{"__ignoreMap":88},[92,22262,22263,22265,22267,22269,22271,22273,22275,22277,22279],{"class":94,"line":95},[92,22264,321],{"class":119},[92,22266,126],{"class":98},[92,22268,6274],{"class":98},[92,22270,6589],{"class":102},[92,22272,120],{"class":119},[92,22274,68],{"class":102},[92,22276,195],{"class":119},[92,22278,354],{"class":102},[92,22280,6289],{"class":119},[92,22282,22283,22285,22287,22289],{"class":94,"line":106},[92,22284,8516],{"class":119},[92,22286,126],{"class":98},[92,22288,8521],{"class":119},[92,22290,8524],{"class":134},[92,22292,22293,22295,22297,22299,22301],{"class":94,"line":113},[92,22294,8529],{"class":119},[92,22296,126],{"class":98},[92,22298,8534],{"class":98},[92,22300,8537],{"class":119},[92,22302,8540],{"class":134},[92,22304,22305],{"class":94,"line":138},[92,22306,110],{"emptyLinePlaceholder":109},[92,22308,22309,22311,22313,22315],{"class":94,"line":143},[92,22310,321],{"class":119},[92,22312,1352],{"class":98},[92,22314,8553],{"class":119},[92,22316,8556],{"class":134},[92,22318,22319,22321,22323,22325],{"class":94,"line":149},[92,22320,321],{"class":119},[92,22322,1352],{"class":98},[92,22324,8565],{"class":119},[92,22326,8568],{"class":134},[92,22328,22329,22331,22333,22335],{"class":94,"line":155},[92,22330,321],{"class":119},[92,22332,1344],{"class":98},[92,22334,8577],{"class":119},[92,22336,8580],{"class":134},[92,22338,22339],{"class":94,"line":161},[92,22340,110],{"emptyLinePlaceholder":109},[92,22342,22343,22345,22347,22349,22351,22353],{"class":94,"line":166},[92,22344,7878],{"class":119},[92,22346,1996],{"class":98},[92,22348,6548],{"class":119},[92,22350,126],{"class":98},[92,22352,8597],{"class":102},[92,22354,229],{"class":119},[92,22356,22357,22359,22361,22363],{"class":94,"line":187},[92,22358,8604],{"class":119},[92,22360,1996],{"class":98},[92,22362,8609],{"class":119},[92,22364,8612],{"class":134},[242,22366,8616],{"id":8615},[11,22368,8619,22369,8623,22371,8626,22373,8629,22375,8633,22377,8637,22379,6339,22381,81],{},[15,22370,8622],{},[15,22372,5612],{},[15,22374,4497],{},[15,22376,8632],{},[15,22378,8636],{},[15,22380,8640],{},[15,22382,8643],{},[83,22384,22385],{"className":85,"code":8646,"language":87,"meta":88,"style":88},[15,22386,22387,22395,22399,22407,22421,22425,22433,22449,22467,22471],{"__ignoreMap":88},[92,22388,22389,22391,22393],{"class":94,"line":95},[92,22390,8622],{"class":98},[92,22392,8655],{"class":5161},[92,22394,229],{"class":119},[92,22396,22397],{"class":94,"line":106},[92,22398,110],{"emptyLinePlaceholder":109},[92,22400,22401,22403,22405],{"class":94,"line":113},[92,22402,5612],{"class":98},[92,22404,8668],{"class":102},[92,22406,229],{"class":119},[92,22408,22409,22411,22413,22415,22417,22419],{"class":94,"line":138},[92,22410,5612],{"class":98},[92,22412,8677],{"class":102},[92,22414,8680],{"class":98},[92,22416,8683],{"class":5161},[92,22418,309],{"class":119},[92,22420,8688],{"class":134},[92,22422,22423],{"class":94,"line":143},[92,22424,110],{"emptyLinePlaceholder":109},[92,22426,22427,22429,22431],{"class":94,"line":149},[92,22428,6122],{"class":98},[92,22430,8699],{"class":5161},[92,22432,4695],{"class":119},[92,22434,22435,22437,22439,22441,22443,22445,22447],{"class":94,"line":155},[92,22436,6132],{"class":98},[92,22438,5659],{"class":98},[92,22440,8710],{"class":5161},[92,22442,6042],{"class":119},[92,22444,5185],{"class":98},[92,22446,5188],{"class":98},[92,22448,4695],{"class":119},[92,22450,22451,22453,22455,22457,22459,22461,22463,22465],{"class":94,"line":161},[92,22452,6236],{"class":98},[92,22454,8725],{"class":102},[92,22456,6818],{"class":98},[92,22458,8730],{"class":5161},[92,22460,120],{"class":119},[92,22462,2315],{"class":171},[92,22464,131],{"class":119},[92,22466,8739],{"class":134},[92,22468,22469],{"class":94,"line":166},[92,22470,5104],{"class":119},[92,22472,22473],{"class":94,"line":187},[92,22474,4711],{"class":119},[39,22476,8751],{"id":8750},[242,22478,8755],{"id":8754},[11,22480,8758,22481,8762,22483,8766,22485,8770,22487,8773],{},[15,22482,8761],{},[15,22484,8765],{},[15,22486,8769],{},[15,22488,1810],{},[83,22490,22491],{"className":85,"code":8776,"language":87,"meta":88,"style":88},[15,22492,22493,22499,22521,22527,22545,22559,22573,22593,22601,22609],{"__ignoreMap":88},[92,22494,22495,22497],{"class":94,"line":95},[92,22496,8761],{"class":98},[92,22498,4695],{"class":119},[92,22500,22501,22503,22505,22507,22509,22511,22513,22515,22517,22519],{"class":94,"line":106},[92,22502,8789],{"class":119},[92,22504,126],{"class":98},[92,22506,8794],{"class":102},[92,22508,8797],{"class":119},[92,22510,474],{"class":102},[92,22512,195],{"class":119},[92,22514,8804],{"class":5161},[92,22516,5263],{"class":119},[92,22518,8809],{"class":102},[92,22520,6289],{"class":119},[92,22522,22523,22525],{"class":94,"line":113},[92,22524,8816],{"class":5161},[92,22526,8819],{"class":119},[92,22528,22529,22531,22533,22535,22537,22539,22541,22543],{"class":94,"line":138},[92,22530,4664],{"class":119},[92,22532,8765],{"class":98},[92,22534,3559],{"class":119},[92,22536,8830],{"class":102},[92,22538,8833],{"class":119},[92,22540,8836],{"class":102},[92,22542,8839],{"class":119},[92,22544,8842],{"class":134},[92,22546,22547,22549,22551,22553,22555,22557],{"class":94,"line":143},[92,22548,5314],{"class":102},[92,22550,8849],{"class":119},[92,22552,1996],{"class":98},[92,22554,8854],{"class":5161},[92,22556,8857],{"class":119},[92,22558,8860],{"class":134},[92,22560,22561,22563,22565,22567,22569,22571],{"class":94,"line":149},[92,22562,5314],{"class":102},[92,22564,8849],{"class":119},[92,22566,1996],{"class":98},[92,22568,8871],{"class":5161},[92,22570,8874],{"class":119},[92,22572,8877],{"class":134},[92,22574,22575,22577,22579,22581,22583,22585,22587,22589,22591],{"class":94,"line":155},[92,22576,8882],{"class":98},[92,22578,6274],{"class":98},[92,22580,1945],{"class":102},[92,22582,120],{"class":119},[92,22584,8891],{"class":171},[92,22586,195],{"class":119},[92,22588,8896],{"class":5161},[92,22590,8899],{"class":119},[92,22592,8902],{"class":134},[92,22594,22595,22597,22599],{"class":94,"line":161},[92,22596,4664],{"class":119},[92,22598,8769],{"class":98},[92,22600,4695],{"class":119},[92,22602,22603,22605,22607],{"class":94,"line":166},[92,22604,8915],{"class":5161},[92,22606,8918],{"class":119},[92,22608,8921],{"class":134},[92,22610,22611],{"class":94,"line":187},[92,22612,4711],{"class":119},[242,22614,8929],{"id":8928},[11,22616,8932,22617,8936,22619,8939,22621,8943,22623,6339,22625,8948],{},[15,22618,8935],{},[15,22620,8935],{},[1511,22622,8942],{},[15,22624,1733],{},[15,22626,1713],{},[83,22628,22629],{"className":85,"code":8951,"language":87,"meta":88,"style":88},[15,22630,22631,22649,22661,22683],{"__ignoreMap":88},[92,22632,22633,22635,22637,22639,22641,22643,22645,22647],{"class":94,"line":95},[92,22634,3556],{"class":98},[92,22636,8960],{"class":5161},[92,22638,120],{"class":119},[92,22640,370],{"class":98},[92,22642,8967],{"class":119},[92,22644,5185],{"class":98},[92,22646,8699],{"class":102},[92,22648,4695],{"class":119},[92,22650,22651,22653,22655,22657,22659],{"class":94,"line":106},[92,22652,5195],{"class":98},[92,22654,8980],{"class":119},[92,22656,1996],{"class":98},[92,22658,8985],{"class":5161},[92,22660,8988],{"class":119},[92,22662,22663,22665,22667,22669,22671,22673,22675,22677,22679,22681],{"class":94,"line":113},[92,22664,8993],{"class":98},[92,22666,8996],{"class":98},[92,22668,6274],{"class":98},[92,22670,9001],{"class":102},[92,22672,120],{"class":119},[92,22674,9006],{"class":171},[92,22676,9009],{"class":119},[92,22678,178],{"class":171},[92,22680,131],{"class":119},[92,22682,9016],{"class":134},[92,22684,22685],{"class":94,"line":138},[92,22686,4711],{"class":119},[242,22688,9024],{"id":9023},[11,22690,9027,22691,9031,22693,9035,22695,9039,22697,9042,22699,9046,22701,195,22703,1375,22705,9053,22707,9057,22709,9061,22711,9064,22713,9067,22715,8939,22717,9072,22719,9075,22721,9078],{},[15,22692,9030],{},[15,22694,9034],{},[15,22696,9038],{},[15,22698,1150],{},[15,22700,9045],{},[15,22702,1249],{},[15,22704,1178],{},[15,22706,529],{},[15,22708,9056],{},[15,22710,9060],{},[1511,22712,5608],{},[15,22714,1150],{},[15,22716,1150],{},[15,22718,9038],{},[15,22720,9034],{},[15,22722,9030],{},[11,22724,22725],{},[3108,22726],{"alt":9083,"src":9084},[242,22728,9088],{"id":9087},[11,22730,9091,22731,9094,22733,6339,22735,9101,22737,9105,22739,9108],{},[15,22732,9034],{},[15,22734,9097],{},[15,22736,9100],{},[15,22738,9104],{},[15,22740,9100],{},[83,22742,22743],{"className":85,"code":9111,"language":87,"meta":88,"style":88},[15,22744,22745,22757,22761,22783,22797,22821,22825,22829,22833,22837,22843,22853,22867,22879],{"__ignoreMap":88},[92,22746,22747,22749,22751,22753,22755],{"class":94,"line":95},[92,22748,6122],{"class":98},[92,22750,9120],{"class":5161},[92,22752,7096],{"class":98},[92,22754,1945],{"class":102},[92,22756,9127],{"class":119},[92,22758,22759],{"class":94,"line":106},[92,22760,110],{"emptyLinePlaceholder":109},[92,22762,22763,22765,22767,22769,22771,22773,22775,22777,22779,22781],{"class":94,"line":113},[92,22764,3556],{"class":98},[92,22766,9138],{"class":5161},[92,22768,120],{"class":119},[92,22770,9143],{"class":102},[92,22772,9146],{"class":119},[92,22774,370],{"class":98},[92,22776,6396],{"class":119},[92,22778,5185],{"class":98},[92,22780,5303],{"class":98},[92,22782,4695],{"class":119},[92,22784,22785,22787,22789,22791,22793,22795],{"class":94,"line":138},[92,22786,9161],{"class":98},[92,22788,9164],{"class":119},[92,22790,1599],{"class":98},[92,22792,9169],{"class":119},[92,22794,1996],{"class":98},[92,22796,9174],{"class":119},[92,22798,22799,22801,22803,22805,22807,22809,22811,22813,22815,22817,22819],{"class":94,"line":143},[92,22800,9179],{"class":98},[92,22802,6274],{"class":98},[92,22804,9120],{"class":102},[92,22806,120],{"class":119},[92,22808,9188],{"class":171},[92,22810,2108],{"class":98},[92,22812,9164],{"class":119},[92,22814,1966],{"class":98},[92,22816,9169],{"class":119},[92,22818,1996],{"class":98},[92,22820,9201],{"class":119},[92,22822,22823],{"class":94,"line":149},[92,22824,5104],{"class":119},[92,22826,22827],{"class":94,"line":155},[92,22828,9210],{"class":134},[92,22830,22831],{"class":94,"line":161},[92,22832,4711],{"class":119},[92,22834,22835],{"class":94,"line":166},[92,22836,110],{"emptyLinePlaceholder":109},[92,22838,22839,22841],{"class":94,"line":187},[92,22840,8761],{"class":98},[92,22842,4695],{"class":119},[92,22844,22845,22847,22849,22851],{"class":94,"line":217},[92,22846,9229],{"class":5161},[92,22848,9232],{"class":119},[92,22850,9235],{"class":102},[92,22852,6289],{"class":119},[92,22854,22855,22857,22859,22861,22863,22865],{"class":94,"line":712},[92,22856,4664],{"class":119},[92,22858,8765],{"class":98},[92,22860,3559],{"class":119},[92,22862,9248],{"class":102},[92,22864,8839],{"class":119},[92,22866,9253],{"class":134},[92,22868,22869,22871,22873,22875,22877],{"class":94,"line":730},[92,22870,9258],{"class":5161},[92,22872,9261],{"class":119},[92,22874,1996],{"class":98},[92,22876,8854],{"class":5161},[92,22878,9268],{"class":119},[92,22880,22881],{"class":94,"line":747},[92,22882,4711],{"class":119},[11,22884,9275,22885,9279,22887,9282,22889,9285,22891,9288],{},[15,22886,9278],{},[15,22888,9038],{},[15,22890,9034],{},[15,22892,1830],{},[39,22894,9292],{"id":9291},[242,22896,9296],{"id":9295},[11,22898,9299,22899,9303,22901,9307,22903,9311,22905,9314,22907,6339,22909,9321],{},[15,22900,9302],{},[15,22902,9306],{},[15,22904,9310],{},[15,22906,474],{},[15,22908,9317],{},[15,22910,9320],{},[83,22912,22913],{"className":85,"code":9324,"language":87,"meta":88,"style":88},[15,22914,22915,22945,22949,22955,22959,22963,22969,22973,22977],{"__ignoreMap":88},[92,22916,22917,22919,22921,22923,22925,22927,22929,22931,22933,22935,22937,22939,22941,22943],{"class":94,"line":95},[92,22918,9331],{"class":119},[92,22920,126],{"class":98},[92,22922,347],{"class":119},[92,22924,1016],{"class":171},[92,22926,1019],{"class":98},[92,22928,271],{"class":171},[92,22930,195],{"class":119},[92,22932,9346],{"class":171},[92,22934,1019],{"class":98},[92,22936,347],{"class":119},[92,22938,9353],{"class":171},[92,22940,195],{"class":119},[92,22942,9358],{"class":171},[92,22944,9361],{"class":119},[92,22946,22947],{"class":94,"line":106},[92,22948,110],{"emptyLinePlaceholder":109},[92,22950,22951,22953],{"class":94,"line":113},[92,22952,9370],{"class":102},[92,22954,8819],{"class":119},[92,22956,22957],{"class":94,"line":138},[92,22958,9377],{"class":134},[92,22960,22961],{"class":94,"line":143},[92,22962,110],{"emptyLinePlaceholder":109},[92,22964,22965,22967],{"class":94,"line":149},[92,22966,9317],{"class":102},[92,22968,8819],{"class":119},[92,22970,22971],{"class":94,"line":155},[92,22972,9392],{"class":134},[92,22974,22975],{"class":94,"line":161},[92,22976,110],{"emptyLinePlaceholder":109},[92,22978,22979,22981,22983,22985,22987,22989,22991],{"class":94,"line":166},[92,22980,9401],{"class":119},[92,22982,126],{"class":98},[92,22984,9406],{"class":102},[92,22986,9409],{"class":119},[92,22988,474],{"class":102},[92,22990,131],{"class":119},[92,22992,9416],{"class":134},[242,22994,9420],{"id":9419},[11,22996,9423,22997,9426,22999,9430,23001,529,23003,9435,23005,9439,23007,9443],{},[15,22998,1249],{},[15,23000,9429],{},[15,23002,4036],{},[15,23004,4042],{},[15,23006,9438],{},[15,23008,9442],{},[83,23010,23011],{"className":85,"code":9446,"language":87,"meta":88,"style":88},[15,23012,23013,23027,23039,23051,23067,23079,23091,23107,23119,23135,23155,23175,23191],{"__ignoreMap":88},[92,23014,23015,23017,23019,23021,23023,23025],{"class":94,"line":95},[92,23016,9453],{"class":102},[92,23018,120],{"class":119},[92,23020,1966],{"class":98},[92,23022,1463],{"class":102},[92,23024,2414],{"class":119},[92,23026,9464],{"class":134},[92,23028,23029,23031,23033,23035,23037],{"class":94,"line":106},[92,23030,9469],{"class":102},[92,23032,120],{"class":119},[92,23034,9474],{"class":102},[92,23036,2441],{"class":119},[92,23038,9479],{"class":134},[92,23040,23041,23043,23045,23047,23049],{"class":94,"line":113},[92,23042,9484],{"class":102},[92,23044,120],{"class":119},[92,23046,9489],{"class":102},[92,23048,2378],{"class":119},[92,23050,9494],{"class":134},[92,23052,23053,23055,23057,23059,23061,23063,23065],{"class":94,"line":138},[92,23054,9499],{"class":102},[92,23056,120],{"class":119},[92,23058,9504],{"class":102},[92,23060,195],{"class":119},[92,23062,354],{"class":102},[92,23064,2770],{"class":119},[92,23066,9513],{"class":134},[92,23068,23069,23071,23073,23075,23077],{"class":94,"line":143},[92,23070,9518],{"class":102},[92,23072,120],{"class":119},[92,23074,9523],{"class":102},[92,23076,2441],{"class":119},[92,23078,9528],{"class":134},[92,23080,23081,23083,23085,23087,23089],{"class":94,"line":149},[92,23082,354],{"class":102},[92,23084,1283],{"class":98},[92,23086,1286],{"class":102},[92,23088,9539],{"class":119},[92,23090,9542],{"class":134},[92,23092,23093,23095,23097,23099,23101,23103,23105],{"class":94,"line":155},[92,23094,1249],{"class":102},[92,23096,120],{"class":119},[92,23098,9551],{"class":102},[92,23100,195],{"class":119},[92,23102,1463],{"class":102},[92,23104,433],{"class":119},[92,23106,9560],{"class":134},[92,23108,23109,23111,23113,23115,23117],{"class":94,"line":161},[92,23110,9551],{"class":102},[92,23112,1269],{"class":98},[92,23114,1315],{"class":102},[92,23116,9571],{"class":119},[92,23118,2582],{"class":134},[92,23120,23121,23123,23125,23127,23129,23131,23133],{"class":94,"line":166},[92,23122,9429],{"class":102},[92,23124,120],{"class":119},[92,23126,9582],{"class":102},[92,23128,195],{"class":119},[92,23130,354],{"class":102},[92,23132,9589],{"class":119},[92,23134,9592],{"class":134},[92,23136,23137,23139,23141,23143,23145,23147,23149,23151,23153],{"class":94,"line":187},[92,23138,4036],{"class":102},[92,23140,120],{"class":119},[92,23142,1448],{"class":102},[92,23144,195],{"class":119},[92,23146,1205],{"class":102},[92,23148,195],{"class":119},[92,23150,354],{"class":102},[92,23152,9589],{"class":119},[92,23154,9613],{"class":134},[92,23156,23157,23159,23161,23163,23165,23167,23169,23171,23173],{"class":94,"line":217},[92,23158,4042],{"class":102},[92,23160,486],{"class":119},[92,23162,1448],{"class":102},[92,23164,195],{"class":119},[92,23166,1205],{"class":102},[92,23168,195],{"class":119},[92,23170,354],{"class":102},[92,23172,627],{"class":119},[92,23174,2582],{"class":134},[92,23176,23177,23179,23181,23183,23185,23187,23189],{"class":94,"line":712},[92,23178,9638],{"class":5161},[92,23180,120],{"class":119},[92,23182,68],{"class":102},[92,23184,195],{"class":119},[92,23186,1235],{"class":102},[92,23188,599],{"class":119},[92,23190,9651],{"class":134},[92,23192,23193,23195,23197,23199,23201,23203,23205],{"class":94,"line":730},[92,23194,2758],{"class":102},[92,23196,120],{"class":119},[92,23198,9660],{"class":102},[92,23200,195],{"class":119},[92,23202,354],{"class":102},[92,23204,653],{"class":119},[92,23206,9669],{"class":134},[242,23208,9673],{"id":9672},[11,23210,23211,9679,23213,9683,23215,9687,23217,9690,23219,9694,23221,9697,23223,9700,23225,9703,23227,81],{},[15,23212,9678],{},[15,23214,9682],{},[15,23216,9686],{},[15,23218,474],{},[15,23220,9693],{},[15,23222,1996],{},[15,23224,8809],{},[15,23226,8830],{},[15,23228,390],{},[83,23230,23231],{"className":85,"code":9708,"language":87,"meta":88,"style":88},[15,23232,23233,23265,23269,23273,23289,23301,23305],{"__ignoreMap":88},[92,23234,23235,23237,23239,23241,23243,23245,23247,23249,23251,23253,23255,23257,23259,23261,23263],{"class":94,"line":95},[92,23236,9715],{"class":119},[92,23238,126],{"class":98},[92,23240,9720],{"class":102},[92,23242,486],{"class":119},[92,23244,1016],{"class":171},[92,23246,1019],{"class":98},[92,23248,271],{"class":171},[92,23250,195],{"class":119},[92,23252,9733],{"class":171},[92,23254,1019],{"class":98},[92,23256,347],{"class":119},[92,23258,1844],{"class":171},[92,23260,195],{"class":119},[92,23262,198],{"class":171},[92,23264,9746],{"class":119},[92,23266,23267],{"class":94,"line":106},[92,23268,9751],{"class":134},[92,23270,23271],{"class":94,"line":113},[92,23272,110],{"emptyLinePlaceholder":109},[92,23274,23275,23277,23279,23281,23283,23285,23287],{"class":94,"line":138},[92,23276,9760],{"class":119},[92,23278,126],{"class":98},[92,23280,8794],{"class":102},[92,23282,9767],{"class":119},[92,23284,474],{"class":102},[92,23286,131],{"class":119},[92,23288,9774],{"class":134},[92,23290,23291,23293,23295,23297,23299],{"class":94,"line":143},[92,23292,9779],{"class":119},[92,23294,126],{"class":98},[92,23296,8794],{"class":102},[92,23298,9786],{"class":119},[92,23300,9789],{"class":134},[92,23302,23303],{"class":94,"line":149},[92,23304,110],{"emptyLinePlaceholder":109},[92,23306,23307,23309,23311,23313,23315,23317,23319,23321],{"class":94,"line":155},[92,23308,60],{"class":102},[92,23310,9720],{"class":102},[92,23312,9409],{"class":119},[92,23314,9804],{"class":102},[92,23316,1909],{"class":98},[92,23318,9809],{"class":102},[92,23320,800],{"class":119},[92,23322,9814],{"class":134},[242,23324,9818],{"id":9817},[11,23326,9821,23327,9825,23329,9829,23331,9833,23333,9837],{},[15,23328,9824],{},[15,23330,9828],{},[15,23332,9832],{},[15,23334,9836],{},[83,23336,23337],{"className":85,"code":9840,"language":87,"meta":88,"style":88},[15,23338,23339,23351,23359,23371,23375,23391,23411,23427],{"__ignoreMap":88},[92,23340,23341,23343,23345,23347,23349],{"class":94,"line":95},[92,23342,9847],{"class":102},[92,23344,120],{"class":119},[92,23346,9852],{"class":171},[92,23348,9855],{"class":119},[92,23350,9858],{"class":134},[92,23352,23353,23355,23357],{"class":94,"line":106},[92,23354,9863],{"class":102},[92,23356,9866],{"class":119},[92,23358,9869],{"class":134},[92,23360,23361,23363,23365,23367,23369],{"class":94,"line":113},[92,23362,9874],{"class":102},[92,23364,120],{"class":119},[92,23366,9879],{"class":171},[92,23368,2414],{"class":119},[92,23370,9884],{"class":134},[92,23372,23373],{"class":94,"line":138},[92,23374,110],{"emptyLinePlaceholder":109},[92,23376,23377,23379,23381,23383,23385,23387,23389],{"class":94,"line":143},[92,23378,9893],{"class":119},[92,23380,126],{"class":98},[92,23382,6274],{"class":98},[92,23384,9900],{"class":102},[92,23386,120],{"class":119},[92,23388,9905],{"class":171},[92,23390,6289],{"class":119},[92,23392,23393,23395,23397,23399,23401,23403,23405,23407,23409],{"class":94,"line":149},[92,23394,9912],{"class":119},[92,23396,126],{"class":98},[92,23398,9917],{"class":119},[92,23400,1996],{"class":98},[92,23402,9922],{"class":5161},[92,23404,120],{"class":119},[92,23406,9927],{"class":171},[92,23408,131],{"class":119},[92,23410,9932],{"class":134},[92,23412,23413,23415,23417,23419,23421,23423,23425],{"class":94,"line":155},[92,23414,9937],{"class":119},[92,23416,1996],{"class":98},[92,23418,9942],{"class":5161},[92,23420,120],{"class":119},[92,23422,9852],{"class":171},[92,23424,2333],{"class":119},[92,23426,9951],{"class":134},[92,23428,23429,23431,23433,23435,23437,23439,23441],{"class":94,"line":161},[92,23430,9956],{"class":119},[92,23432,1996],{"class":98},[92,23434,9961],{"class":5161},[92,23436,9964],{"class":119},[92,23438,1996],{"class":98},[92,23440,9969],{"class":119},[92,23442,1215],{"class":134},[242,23444,9975],{"id":9974},[11,23446,9978,23447,9982,23449,9985,23451,9989,23453,195,23455,1375,23457,975,23459,9999,23461,10003,23463,10007],{},[15,23448,9981],{},[15,23450,529],{},[15,23452,9988],{},[15,23454,68],{},[15,23456,554],{},[15,23458,2300],{},[15,23460,9998],{},[15,23462,10002],{},[15,23464,10006],{},[83,23466,23467],{"className":85,"code":10010,"language":87,"meta":88,"style":88},[15,23468,23469,23497,23519,23549,23571],{"__ignoreMap":88},[92,23470,23471,23473,23475,23477,23479,23481,23483,23485,23487,23489,23491,23493,23495],{"class":94,"line":95},[92,23472,9988],{"class":102},[92,23474,120],{"class":119},[92,23476,10021],{"class":171},[92,23478,120],{"class":10024},[92,23480,10028],{"class":10027},[92,23482,10031],{"class":10024},[92,23484,10028],{"class":10027},[92,23486,10036],{"class":10024},[92,23488,10039],{"class":171},[92,23490,195],{"class":119},[92,23492,10044],{"class":171},[92,23494,10047],{"class":119},[92,23496,10050],{"class":134},[92,23498,23499,23501,23503,23505,23507,23509,23511,23513,23515,23517],{"class":94,"line":106},[92,23500,9998],{"class":102},[92,23502,120],{"class":119},[92,23504,10021],{"class":171},[92,23506,10028],{"class":10027},[92,23508,1795],{"class":98},[92,23510,10039],{"class":171},[92,23512,195],{"class":119},[92,23514,10069],{"class":171},[92,23516,10072],{"class":119},[92,23518,10075],{"class":134},[92,23520,23521,23523,23525,23527,23529,23531,23533,23535,23537,23539,23541,23543,23545,23547],{"class":94,"line":113},[92,23522,10002],{"class":102},[92,23524,120],{"class":119},[92,23526,10021],{"class":171},[92,23528,10086],{"class":10027},[92,23530,1795],{"class":98},[92,23532,10039],{"class":171},[92,23534,195],{"class":119},[92,23536,10095],{"class":171},[92,23538,195],{"class":119},[92,23540,10100],{"class":171},[92,23542,1988],{"class":102},[92,23544,10105],{"class":171},[92,23546,653],{"class":119},[92,23548,10110],{"class":134},[92,23550,23551,23553,23555,23557,23559,23561,23563,23565,23567,23569],{"class":94,"line":138},[92,23552,10115],{"class":102},[92,23554,120],{"class":119},[92,23556,10021],{"class":171},[92,23558,10122],{"class":10024},[92,23560,1795],{"class":98},[92,23562,10039],{"class":171},[92,23564,195],{"class":119},[92,23566,10131],{"class":171},[92,23568,10134],{"class":119},[92,23570,2694],{"class":134},[92,23572,23573,23575,23577,23579,23581,23583,23585,23587,23589,23591,23593,23595,23597,23599,23601,23603],{"class":94,"line":143},[92,23574,10006],{"class":102},[92,23576,120],{"class":119},[92,23578,10021],{"class":171},[92,23580,10028],{"class":10027},[92,23582,10039],{"class":171},[92,23584,195],{"class":119},[92,23586,3466],{"class":98},[92,23588,10155],{"class":119},[92,23590,554],{"class":102},[92,23592,1751],{"class":119},[92,23594,1959],{"class":98},[92,23596,1225],{"class":102},[92,23598,195],{"class":119},[92,23600,10168],{"class":171},[92,23602,653],{"class":119},[92,23604,10173],{"class":134},[242,23606,10177],{"id":10176},[11,23608,10180,23609,834,23611,10186,23613,653,23615,10192,23617,529,23619,10199,23621,10203],{},[15,23610,10183],{},[15,23612,4574],{},[15,23614,3214],{},[15,23616,10191],{},[15,23618,10195],{},[15,23620,10198],{},[15,23622,10202],{},[83,23624,23625],{"className":85,"code":10206,"language":87,"meta":88,"style":88},[15,23626,23627,23639,23663,23675,23687,23691,23703,23727,23739,23743,23755,23789,23801,23805,23817,23835,23853],{"__ignoreMap":88},[92,23628,23629,23631,23633,23635,23637],{"class":94,"line":95},[92,23630,10213],{"class":119},[92,23632,126],{"class":98},[92,23634,6274],{"class":98},[92,23636,10220],{"class":102},[92,23638,7730],{"class":119},[92,23640,23641,23643,23645,23647,23649,23651,23653,23655,23657,23659,23661],{"class":94,"line":106},[92,23642,10227],{"class":119},[92,23644,1996],{"class":98},[92,23646,10232],{"class":5161},[92,23648,120],{"class":119},[92,23650,68],{"class":102},[92,23652,10239],{"class":119},[92,23654,1996],{"class":98},[92,23656,10232],{"class":5161},[92,23658,120],{"class":119},[92,23660,354],{"class":102},[92,23662,6289],{"class":119},[92,23664,23665,23667,23669,23671,23673],{"class":94,"line":113},[92,23666,10227],{"class":119},[92,23668,1996],{"class":98},[92,23670,10258],{"class":5161},[92,23672,6302],{"class":119},[92,23674,10263],{"class":134},[92,23676,23677,23679,23681,23683,23685],{"class":94,"line":138},[92,23678,10227],{"class":119},[92,23680,1996],{"class":98},[92,23682,10272],{"class":5161},[92,23684,6302],{"class":119},[92,23686,2582],{"class":134},[92,23688,23689],{"class":94,"line":143},[92,23690,110],{"emptyLinePlaceholder":109},[92,23692,23693,23695,23697,23699,23701],{"class":94,"line":149},[92,23694,10285],{"class":119},[92,23696,126],{"class":98},[92,23698,6274],{"class":98},[92,23700,10292],{"class":102},[92,23702,7730],{"class":119},[92,23704,23705,23707,23709,23711,23713,23715,23717,23719,23721,23723,23725],{"class":94,"line":155},[92,23706,10299],{"class":119},[92,23708,1996],{"class":98},[92,23710,10304],{"class":5161},[92,23712,120],{"class":119},[92,23714,1844],{"class":171},[92,23716,10311],{"class":119},[92,23718,1996],{"class":98},[92,23720,10304],{"class":5161},[92,23722,120],{"class":119},[92,23724,198],{"class":171},[92,23726,6289],{"class":119},[92,23728,23729,23731,23733,23735,23737],{"class":94,"line":161},[92,23730,10299],{"class":119},[92,23732,1996],{"class":98},[92,23734,10330],{"class":5161},[92,23736,10333],{"class":119},[92,23738,10336],{"class":134},[92,23740,23741],{"class":94,"line":166},[92,23742,110],{"emptyLinePlaceholder":109},[92,23744,23745,23747,23749,23751,23753],{"class":94,"line":187},[92,23746,10345],{"class":119},[92,23748,126],{"class":98},[92,23750,6274],{"class":98},[92,23752,10352],{"class":102},[92,23754,7730],{"class":119},[92,23756,23757,23759,23761,23763,23765,23767,23769,23771,23773,23775,23777,23779,23781,23783,23785,23787],{"class":94,"line":217},[92,23758,10359],{"class":119},[92,23760,1996],{"class":98},[92,23762,10364],{"class":5161},[92,23764,120],{"class":119},[92,23766,1463],{"class":102},[92,23768,10371],{"class":119},[92,23770,1996],{"class":98},[92,23772,10364],{"class":5161},[92,23774,120],{"class":119},[92,23776,68],{"class":102},[92,23778,10371],{"class":119},[92,23780,1996],{"class":98},[92,23782,10364],{"class":5161},[92,23784,120],{"class":119},[92,23786,1448],{"class":102},[92,23788,6289],{"class":119},[92,23790,23791,23793,23795,23797,23799],{"class":94,"line":712},[92,23792,10359],{"class":119},[92,23794,1996],{"class":98},[92,23796,10400],{"class":5161},[92,23798,7178],{"class":119},[92,23800,10405],{"class":134},[92,23802,23803],{"class":94,"line":730},[92,23804,110],{"emptyLinePlaceholder":109},[92,23806,23807,23809,23811,23813,23815],{"class":94,"line":747},[92,23808,10414],{"class":119},[92,23810,126],{"class":98},[92,23812,6274],{"class":98},[92,23814,10421],{"class":102},[92,23816,7730],{"class":119},[92,23818,23819,23821,23823,23825,23827,23829,23831,23833],{"class":94,"line":763},[92,23820,10428],{"class":119},[92,23822,1996],{"class":98},[92,23824,10364],{"class":5161},[92,23826,120],{"class":119},[92,23828,10437],{"class":171},[92,23830,195],{"class":119},[92,23832,68],{"class":102},[92,23834,6289],{"class":119},[92,23836,23837,23839,23841,23843,23845,23847,23849,23851],{"class":94,"line":780},[92,23838,10428],{"class":119},[92,23840,1996],{"class":98},[92,23842,10364],{"class":5161},[92,23844,120],{"class":119},[92,23846,10456],{"class":171},[92,23848,195],{"class":119},[92,23850,4419],{"class":102},[92,23852,6289],{"class":119},[92,23854,23855,23857,23859,23861,23863],{"class":94,"line":785},[92,23856,10428],{"class":119},[92,23858,1996],{"class":98},[92,23860,10400],{"class":5161},[92,23862,10473],{"class":119},[92,23864,10476],{"class":134},[11,23866,10479],{},[39,23868,10483],{"id":10482},[11,23870,10486],{},[11,23872,23873,10493,23875,10496,23877,987,23879,10501,23881,10505,23883,10508,23885,10511,23887,10514,23889,10517],{},[10490,23874,10492],{},[15,23876,1344],{},[15,23878,1348],{},[15,23880,474],{},[15,23882,10504],{},[15,23884,2300],{},[15,23886,474],{},[15,23888,1352],{},[15,23890,1344],{},[11,23892,23893,10523,23895,195,23897,195,23899,195,23901,10534,23903,195,23905,10540,23907,10544,23909,834,23911,10551,23913,10554,23915,10558,23917,6339,23919,10563,23921,10566,23923,6339,23925,10571,23927,10574],{},[10490,23894,10522],{},[15,23896,2300],{},[15,23898,554],{},[15,23900,10530],{},[15,23902,10533],{},[15,23904,10537],{},[15,23906,390],{},[15,23908,10543],{},[15,23910,10547],{},[15,23912,10550],{},[15,23914,10537],{},[15,23916,10557],{},[15,23918,390],{},[15,23920,554],{},[15,23922,996],{},[15,23924,971],{},[15,23926,978],{},[15,23928,390],{},[11,23930,23931,10582,23935,10585,23937,10589,23939,10592,23941,10595,23943,10598,23945,10601],{},[10490,23932,23933,10581],{},[15,23934,2449],{},[15,23936,554],{},[15,23938,10588],{},[15,23940,554],{},[15,23942,2300],{},[15,23944,2889],{},[15,23946,2893],{},[11,23948,23949,10607,23951,10610],{},[10490,23950,10606],{},[15,23952,8482],{},[11,23954,23955],{},[3108,23956],{"alt":10615,"src":10616},[11,23958,23959,10624,23963,10628,23965,10632,23967,10636,23969,10640],{},[10490,23960,6686,23961,10623],{},[15,23962,4394],{},[15,23964,10627],{},[15,23966,10631],{},[15,23968,10635],{},[15,23970,10639],{},[11,23972,23973,10648,23977,10652,23979,10656,23981,10660,23983,10664,23985,10667],{},[10490,23974,23975,10647],{},[15,23976,3326],{},[15,23978,10651],{},[15,23980,10655],{},[15,23982,10659],{},[15,23984,10663],{},[15,23986,3341],{},[11,23988,23989,1644,23995,10680,23997,547,23999,10687,24001,10691,24003,10694,24005,10697,24007,10700,24009,10703],{},[10490,23990,23991,10192,23993,10676],{},[15,23992,3584],{},[15,23994,1795],{},[15,23996,10679],{},[15,23998,10683],{},[15,24000,10686],{},[15,24002,10690],{},[15,24004,3584],{},[15,24006,1795],{},[15,24008,3584],{},[15,24010,1795],{},[11,24012,24013,10709,24015,195,24017,10714,24019,10718,24021,1524,24023,10724,24025,10728],{},[10490,24014,10708],{},[15,24016,4099],{},[15,24018,4153],{},[15,24020,10717],{},[15,24022,10721],{},[15,24024,474],{},[15,24026,10727],{},[11,24028,24029,10734,24031,834,24033,10741,24035,10745,24037,195,24039,10750,24041,394,24043,10755,24045,10758],{},[10490,24030,10733],{},[15,24032,10737],{},[15,24034,10740],{},[15,24036,10744],{},[15,24038,68],{},[15,24040,474],{},[15,24042,68],{},[15,24044,390],{},[15,24046,10533],{},[11,24048,24049,1644,24051,10767,24053,6339,24055,10774],{},[10490,24050,10763],{},[15,24052,10766],{},[15,24054,10770],{},[15,24056,10773],{},[11,24058,24059,10780,24061,987,24063,10786,24065,6339,24067,10791,24069,10795],{},[10490,24060,10779],{},[15,24062,10783],{},[15,24064,2300],{},[15,24066,1344],{},[15,24068,1352],{},[15,24070,10794],{},[11,24072,24073,10805,24079,834,24081,10810,24083,10814,24085,1517,24087,10820,24089,1524,24091,10827,24093,10830,24095,834,24097,10835,24099,529,24101,10840],{},[10490,24074,24075,834,24077,10804],{},[15,24076,1495],{},[15,24078,1505],{},[15,24080,1505],{},[15,24082,1508],{},[1511,24084,10813],{},[15,24086,126],{},[15,24088,10819],{},[15,24090,10823],{},[15,24092,10826],{},[15,24094,1508],{},[15,24096,1495],{},[15,24098,1498],{},[15,24100,1505],{},[15,24102,1508],{},[11,24104,24105,1644,24107,195,24109,394,24111,10855,24113,10858,24115,10861,24117,9072,24119,10866,24121,6339,24123,81],{},[10490,24106,10845],{},[15,24108,10848],{},[15,24110,10851],{},[15,24112,10854],{},[15,24114,9045],{},[15,24116,2300],{},[15,24118,9038],{},[15,24120,9034],{},[15,24122,10869],{},[15,24124,10872],{},[11,24126,24127,10878,24129,10882,24131,10885],{},[10490,24128,10877],{},[15,24130,10881],{},[15,24132,17],{},[10887,24134,10889],{},{"title":88,"searchDepth":106,"depth":106,"links":24136},[24137,24138,24145,24152,24158,24166,24170,24178,24193,24199,24207],{"id":41,"depth":106,"text":42},{"id":239,"depth":106,"text":240,"children":24139},[24140,24141,24142,24143,24144],{"id":244,"depth":113,"text":245},{"id":363,"depth":113,"text":364},{"id":514,"depth":113,"text":515},{"id":806,"depth":113,"text":807},{"id":964,"depth":113,"text":965},{"id":1154,"depth":106,"text":1155,"children":24146},[24147,24148,24149,24150,24151],{"id":1158,"depth":113,"text":1159},{"id":1337,"depth":113,"text":1338},{"id":1488,"depth":113,"text":1489},{"id":1628,"depth":113,"text":1629},{"id":1788,"depth":113,"text":1789},{"id":1975,"depth":106,"text":1976,"children":24153},[24154,24155,24156,24157],{"id":1979,"depth":113,"text":1980},{"id":2208,"depth":113,"text":2209},{"id":2285,"depth":113,"text":2286},{"id":2792,"depth":113,"text":2793},{"id":2897,"depth":106,"text":2898,"children":24159},[24160,24161,24162,24163,24164,24165],{"id":2901,"depth":113,"text":2902},{"id":3114,"depth":113,"text":3115},{"id":3315,"depth":113,"text":3316},{"id":3577,"depth":113,"text":3578},{"id":4051,"depth":113,"text":4052},{"id":4383,"depth":113,"text":4384},{"id":4578,"depth":106,"text":4579,"children":24167},[24168,24169],{"id":4582,"depth":113,"text":4583},{"id":4878,"depth":113,"text":4879},{"id":5124,"depth":106,"text":5125,"children":24171},[24172,24173,24174,24175,24176,24177],{"id":5128,"depth":113,"text":5129},{"id":5328,"depth":113,"text":5329},{"id":5486,"depth":113,"text":5487},{"id":5601,"depth":113,"text":5602},{"id":5828,"depth":113,"text":5829},{"id":5921,"depth":113,"text":5922},{"id":6092,"depth":106,"text":6093,"children":24179},[24180,24181,24182,24183,24184,24185,24186,24187,24188,24189,24190,24191,24192],{"id":6096,"depth":113,"text":10936},{"id":6320,"depth":113,"text":6321},{"id":6465,"depth":113,"text":6466},{"id":6682,"depth":113,"text":6683},{"id":6809,"depth":113,"text":6810},{"id":6993,"depth":113,"text":6994},{"id":7184,"depth":113,"text":7185},{"id":7412,"depth":113,"text":7413},{"id":7653,"depth":113,"text":7654},{"id":7902,"depth":113,"text":7903},{"id":8184,"depth":113,"text":8185},{"id":8465,"depth":113,"text":8466},{"id":8615,"depth":113,"text":8616},{"id":8750,"depth":106,"text":8751,"children":24194},[24195,24196,24197,24198],{"id":8754,"depth":113,"text":8755},{"id":8928,"depth":113,"text":8929},{"id":9023,"depth":113,"text":9024},{"id":9087,"depth":113,"text":9088},{"id":9291,"depth":106,"text":9292,"children":24200},[24201,24202,24203,24204,24205,24206],{"id":9295,"depth":113,"text":9296},{"id":9419,"depth":113,"text":9420},{"id":9672,"depth":113,"text":9673},{"id":9817,"depth":113,"text":9818},{"id":9974,"depth":113,"text":9975},{"id":10176,"depth":113,"text":10177},{"id":10482,"depth":106,"text":10483},{},{"title":5,"description":10965},[10975,10976,10977,10978,10979],{"id":24212,"title":24213,"author":6,"body":24214,"date":10964,"description":31332,"draft":10966,"extension":10967,"guide":10968,"image":31333,"meta":31334,"navigation":109,"path":31335,"seo":31336,"stem":31337,"tags":31338,"__hash__":31341},"blog/Backend/9.go-syntax-recap.md","Go Syntax Recap: Learn Go Fast",{"type":8,"value":24215,"toc":31272},[24216,24219,24222,24231,24235,24254,24367,24370,24405,24407,24409,24419,24510,24514,24525,24560,24564,24632,24636,24649,24757,24761,24785,24875,24877,24880,24943,24972,25043,25047,25051,25068,25177,25181,25195,25298,25302,25311,25647,25661,25665,25669,25683,25792,25796,25799,25832,25838,25842,26038,26042,26045,26135,26139,26150,26353,26360,26435,26439,26450,26592,26607,26609,26613,26637,26859,26863,26869,26899,26904,27008,27015,27086,27088,27092,27103,27262,27266,27276,27486,27490,27502,27639,27649,27774,27778,27781,27785,27799,27950,27954,27961,27979,28101,28105,28112,28252,28254,28268,28399,28412,28561,28565,28588,28594,28598,28602,28619,28738,28742,28761,28930,28934,28940,29095,29098,29122,29126,29132,29136,29145,29193,29197,29208,29233,29409,29415,29418,29433,29550,29554,29561,29607,29783,29794,29798,29822,30142,30144,30148,30163,30242,30355,30359,30377,30532,30534,30544,30678,30682,30689,31021,31025,31128,31132,31135,31269],[11,24217,24218],{},"Go is a deliberately small language. It gives you one loop keyword, no exceptions, no inheritance, and a concurrency model built into the syntax rather than a library.",[11,24220,24221],{},"This article will teach you Go or Golang syntax and all important stuffs in one sitting. If you have a Go interview it's a quick recap for you and if you're learning it first time then also it'll teach you Go faster than any tutorial. Every concept is paired with code you can run.",[11,24223,24224,24225,24227,24228,81],{},"If you're preparing for a backend round, read it alongside the framework-agnostic ",[23,24226,31],{"href":30},". If in case you happen to be a PHP developer as well, you can read ",[23,24229,24230],{"href":15354},"PHP Syntax Recap",[39,24232,24234],{"id":24233},"how-to-read-and-run-go","How to Read and Run Go",[11,24236,24237,24238,24241,24242,24245,24246,24249,24250,24253],{},"Every Go program is a set of packages, and an executable starts in ",[15,24239,24240],{},"package main"," at the ",[15,24243,24244],{},"func main()"," entry point. Imports are explicit and, importantly, an unused import or an unused local variable is a ",[1511,24247,24248],{},"compile error",", not a warning, which keeps files clean but surprises newcomers. Identifiers that start with an uppercase letter are exported (visible outside their package); lowercase ones are package-private. Go inserts semicolons for you, so you never write them, and ",[15,24251,24252],{},"gofmt"," enforces one canonical formatting so style debates do not exist.",[83,24255,24259],{"className":24256,"code":24257,"language":24258,"meta":88,"style":88},"language-go shiki shiki-themes github-dark","package main\n\nimport (\n    \"fmt\"      // used below; an unused import would fail to compile\n    \"strings\"\n)\n\n// main is the entry point of an executable program.\nfunc main() {\n    msg := strings.ToUpper(\"hello\")\n    fmt.Println(msg) // HELLO\n}\n","go",[15,24260,24261,24269,24273,24281,24294,24303,24308,24312,24317,24328,24349,24363],{"__ignoreMap":88},[92,24262,24263,24266],{"class":94,"line":95},[92,24264,24265],{"class":98},"package",[92,24267,24268],{"class":5161}," main\n",[92,24270,24271],{"class":94,"line":106},[92,24272,110],{"emptyLinePlaceholder":109},[92,24274,24275,24278],{"class":94,"line":113},[92,24276,24277],{"class":98},"import",[92,24279,24280],{"class":119}," (\n",[92,24282,24283,24286,24289,24291],{"class":94,"line":138},[92,24284,24285],{"class":171},"    \"",[92,24287,24288],{"class":5161},"fmt",[92,24290,178],{"class":171},[92,24292,24293],{"class":134},"      // used below; an unused import would fail to compile\n",[92,24295,24296,24298,24300],{"class":94,"line":143},[92,24297,24285],{"class":171},[92,24299,1975],{"class":5161},[92,24301,24302],{"class":171},"\"\n",[92,24304,24305],{"class":94,"line":149},[92,24306,24307],{"class":119},")\n",[92,24309,24310],{"class":94,"line":155},[92,24311,110],{"emptyLinePlaceholder":109},[92,24313,24314],{"class":94,"line":161},[92,24315,24316],{"class":134},"// main is the entry point of an executable program.\n",[92,24318,24319,24322,24325],{"class":94,"line":166},[92,24320,24321],{"class":98},"func",[92,24323,24324],{"class":5161}," main",[92,24326,24327],{"class":119},"() {\n",[92,24329,24330,24333,24336,24339,24342,24344,24347],{"class":94,"line":187},[92,24331,24332],{"class":119},"    msg ",[92,24334,24335],{"class":98},":=",[92,24337,24338],{"class":119}," strings.",[92,24340,24341],{"class":5161},"ToUpper",[92,24343,120],{"class":119},[92,24345,24346],{"class":171},"\"hello\"",[92,24348,24307],{"class":119},[92,24350,24351,24354,24357,24360],{"class":94,"line":217},[92,24352,24353],{"class":119},"    fmt.",[92,24355,24356],{"class":5161},"Println",[92,24358,24359],{"class":119},"(msg) ",[92,24361,24362],{"class":134},"// HELLO\n",[92,24364,24365],{"class":94,"line":712},[92,24366,4711],{"class":119},[11,24368,24369],{},"The commands you actually use are few:",[11016,24371,24372,24378,24384,24390,24396],{},[11019,24373,24374,24377],{},[15,24375,24376],{},"go run main.go"," compiles and runs in one step, for quick iteration.",[11019,24379,24380,24383],{},[15,24381,24382],{},"go build"," produces a standalone binary with no runtime dependency.",[11019,24385,24386,24389],{},[15,24387,24388],{},"go test ./..."," runs every test in the module.",[11019,24391,24392,24395],{},[15,24393,24394],{},"go vet ./..."," catches suspicious code that compiles but is probably wrong.",[11019,24397,24398,1357,24401,24404],{},[15,24399,24400],{},"gofmt -w .",[15,24402,24403],{},"go fmt",") formats your code to the canonical style.",[39,24406,240],{"id":239},[242,24408,245],{"id":244},[11,24410,24411,24412,24415,24416,24418],{},"Go gives you two ways to declare a variable, and the difference is where you can use each. The ",[15,24413,24414],{},"var"," keyword works everywhere and lets you state the type explicitly; the short form ",[15,24417,24335],{}," infers the type from the value but only works inside a function. Every variable you declare must be used, and you can assign several at once.",[83,24420,24422],{"className":24256,"code":24421,"language":24258,"meta":88,"style":88},"var count int = 42       // explicit type\nvar name = \"Ada\"         // type inferred as string\nage := 36                // short form; only inside functions\nx, y := 1, 2             // multiple assignment\nx, y = y, x              // swap without a temp variable\n\nvar ready bool           // declared without a value: gets the zero value (false)\n",[15,24423,24424,24440,24455,24467,24483,24494,24498],{"__ignoreMap":88},[92,24425,24426,24428,24431,24433,24435,24437],{"class":94,"line":95},[92,24427,24414],{"class":98},[92,24429,24430],{"class":119}," count ",[92,24432,370],{"class":98},[92,24434,853],{"class":98},[92,24436,283],{"class":102},[92,24438,24439],{"class":134},"       // explicit type\n",[92,24441,24442,24444,24447,24449,24452],{"class":94,"line":106},[92,24443,24414],{"class":98},[92,24445,24446],{"class":119}," name ",[92,24448,126],{"class":98},[92,24450,24451],{"class":171}," \"Ada\"",[92,24453,24454],{"class":134},"         // type inferred as string\n",[92,24456,24457,24460,24462,24464],{"class":94,"line":113},[92,24458,24459],{"class":119},"age ",[92,24461,24335],{"class":98},[92,24463,2979],{"class":102},[92,24465,24466],{"class":134},"                // short form; only inside functions\n",[92,24468,24469,24472,24474,24476,24478,24480],{"class":94,"line":138},[92,24470,24471],{"class":119},"x, y ",[92,24473,24335],{"class":98},[92,24475,1849],{"class":102},[92,24477,195],{"class":119},[92,24479,354],{"class":102},[92,24481,24482],{"class":134},"             // multiple assignment\n",[92,24484,24485,24487,24489,24492],{"class":94,"line":143},[92,24486,24471],{"class":119},[92,24488,126],{"class":98},[92,24490,24491],{"class":119}," y, x              ",[92,24493,4483],{"class":134},[92,24495,24496],{"class":94,"line":149},[92,24497,110],{"emptyLinePlaceholder":109},[92,24499,24500,24502,24505,24507],{"class":94,"line":155},[92,24501,24414],{"class":98},[92,24503,24504],{"class":119}," ready ",[92,24506,379],{"class":98},[92,24508,24509],{"class":134},"           // declared without a value: gets the zero value (false)\n",[242,24511,24513],{"id":24512},"zero-values","Zero values",[11,24515,24516,24517,24520,24521,24524],{},"Go has no concept of an uninitialized variable: anything you declare without a value gets a well-defined ",[1511,24518,24519],{},"zero value",", which removes a whole class of \"undefined\" bugs. Knowing the zero values matters because idiomatic Go relies on them (a zero-value ",[15,24522,24523],{},"sync.Mutex"," is ready to use, a nil slice is safe to append to).",[11016,24526,24527,24538,24544,24551,24557],{},[11019,24528,24529,24530,195,24532,24535,24536],{},"Numeric types (",[15,24531,370],{},[15,24533,24534],{},"float64",", and so on): ",[15,24537,554],{},[11019,24539,24540,5263,24542],{},[15,24541,379],{},[15,24543,2300],{},[11019,24545,24546,5263,24548,24550],{},[15,24547,376],{},[15,24549,10533],{}," (empty, not nil)",[11019,24552,24553,24554],{},"Pointers, slices, maps, channels, functions, interfaces: ",[15,24555,24556],{},"nil",[11019,24558,24559],{},"A struct: every field set to its own zero value",[242,24561,24563],{"id":24562},"the-basic-types","The basic types",[11016,24565,24566,24571,24602,24617,24626],{},[11019,24567,24568,24569,81],{},"Booleans: ",[15,24570,379],{},[11019,24572,24573,24574,195,24576,195,24579,195,24582,195,24585,24588,24589,195,24592,4599,24595,24598,24599,24601],{},"Integers: ",[15,24575,370],{},[15,24577,24578],{},"int8",[15,24580,24581],{},"int16",[15,24583,24584],{},"int32",[15,24586,24587],{},"int64"," and unsigned ",[15,24590,24591],{},"uint",[15,24593,24594],{},"uint8",[15,24596,24597],{},"uint64",". Plain ",[15,24600,370],{}," is 64-bit on modern platforms.",[11019,24603,24604,24605,24608,24609,1361,24611,24608,24614,24616],{},"Aliases you see constantly: ",[15,24606,24607],{},"byte"," (an alias for ",[15,24610,24594],{},[15,24612,24613],{},"rune",[15,24615,24584],{},", used for a Unicode code point).",[11019,24618,24619,24620,195,24623,24625],{},"Floats: ",[15,24621,24622],{},"float32",[15,24624,24534],{}," (default for a decimal literal).",[11019,24627,24628,24629,24631],{},"Strings: ",[15,24630,376],{},", which is immutable and holds UTF-8 bytes.",[242,24633,24635],{"id":24634},"type-conversions","Type conversions",[11,24637,24638,24639,24642,24643,24645,24646,24648],{},"Go never converts between types implicitly, not even between numeric types, so you convert explicitly with ",[15,24640,24641],{},"T(v)",". This is stricter than C, Java, or JavaScript, and it is intentional: an unexpected ",[15,24644,370],{},"-to-",[15,24647,373],{}," promotion cannot silently change a result.",[83,24650,24652],{"className":24256,"code":24651,"language":24258,"meta":88,"style":88},"i := 42\nf := float64(i)      // int to float64, required; there is no implicit promotion\nu := uint(f)         // float64 to uint (truncates toward zero)\nb := []byte(\"hi\")    // string to byte slice\ns := string(b)       // byte slice back to string\nr := string(rune(65)) // \"A\": an int code point to its string, via rune\n",[15,24653,24654,24664,24680,24696,24719,24734],{"__ignoreMap":88},[92,24655,24656,24659,24661],{"class":94,"line":95},[92,24657,24658],{"class":119},"i ",[92,24660,24335],{"class":98},[92,24662,24663],{"class":102}," 42\n",[92,24665,24666,24669,24671,24674,24677],{"class":94,"line":106},[92,24667,24668],{"class":119},"f ",[92,24670,24335],{"class":98},[92,24672,24673],{"class":98}," float64",[92,24675,24676],{"class":119},"(i)      ",[92,24678,24679],{"class":134},"// int to float64, required; there is no implicit promotion\n",[92,24681,24682,24685,24687,24690,24693],{"class":94,"line":113},[92,24683,24684],{"class":119},"u ",[92,24686,24335],{"class":98},[92,24688,24689],{"class":98}," uint",[92,24691,24692],{"class":119},"(f)         ",[92,24694,24695],{"class":134},"// float64 to uint (truncates toward zero)\n",[92,24697,24698,24701,24703,24706,24708,24710,24713,24716],{"class":94,"line":138},[92,24699,24700],{"class":119},"b ",[92,24702,24335],{"class":98},[92,24704,24705],{"class":119}," []",[92,24707,24607],{"class":98},[92,24709,120],{"class":119},[92,24711,24712],{"class":171},"\"hi\"",[92,24714,24715],{"class":119},")    ",[92,24717,24718],{"class":134},"// string to byte slice\n",[92,24720,24721,24724,24726,24728,24731],{"class":94,"line":143},[92,24722,24723],{"class":119},"s ",[92,24725,24335],{"class":98},[92,24727,5188],{"class":98},[92,24729,24730],{"class":119},"(b)       ",[92,24732,24733],{"class":134},"// byte slice back to string\n",[92,24735,24736,24738,24740,24742,24744,24746,24748,24751,24754],{"class":94,"line":149},[92,24737,7359],{"class":119},[92,24739,24335],{"class":98},[92,24741,5188],{"class":98},[92,24743,120],{"class":119},[92,24745,24613],{"class":98},[92,24747,120],{"class":119},[92,24749,24750],{"class":102},"65",[92,24752,24753],{"class":119},")) ",[92,24755,24756],{"class":134},"// \"A\": an int code point to its string, via rune\n",[242,24758,24760],{"id":24759},"named-types-and-constants","Named types and constants",[11,24762,24763,24764,24767,24768,24771,24772,24774,24775,24777,24778,24781,24782,24784],{},"You create a new named type with ",[15,24765,24766],{},"type",", which is how you give meaning to a plain value (a ",[15,24769,24770],{},"type UserID int"," cannot be mixed up with an ordinary ",[15,24773,370],{}," by accident). Constants are declared with ",[15,24776,816],{},", and the ",[15,24779,24780],{},"iota"," counter inside a ",[15,24783,816],{}," block generates successive values, which is Go's idiom for enumerations.",[83,24786,24788],{"className":24256,"code":24787,"language":24258,"meta":88,"style":88},"type Celsius float64          // a distinct type, not just an alias\ntype Status int\n\nconst (\n    Pending  Status = iota // 0\n    Active                 // 1 (iota increments automatically)\n    Archived               // 2\n)\n\nconst MaxRetries = 3          // untyped constant, adapts to context\n",[15,24789,24790,24802,24811,24815,24821,24837,24845,24853,24857,24861],{"__ignoreMap":88},[92,24791,24792,24794,24797,24799],{"class":94,"line":95},[92,24793,24766],{"class":98},[92,24795,24796],{"class":5161}," Celsius",[92,24798,24673],{"class":98},[92,24800,24801],{"class":134},"          // a distinct type, not just an alias\n",[92,24803,24804,24806,24808],{"class":94,"line":106},[92,24805,24766],{"class":98},[92,24807,8003],{"class":5161},[92,24809,24810],{"class":98}," int\n",[92,24812,24813],{"class":94,"line":113},[92,24814,110],{"emptyLinePlaceholder":109},[92,24816,24817,24819],{"class":94,"line":138},[92,24818,816],{"class":98},[92,24820,24280],{"class":119},[92,24822,24823,24826,24829,24831,24834],{"class":94,"line":143},[92,24824,24825],{"class":102},"    Pending",[92,24827,24828],{"class":5161},"  Status",[92,24830,853],{"class":98},[92,24832,24833],{"class":102}," iota",[92,24835,24836],{"class":134}," // 0\n",[92,24838,24839,24842],{"class":94,"line":149},[92,24840,24841],{"class":102},"    Active",[92,24843,24844],{"class":134},"                 // 1 (iota increments automatically)\n",[92,24846,24847,24850],{"class":94,"line":155},[92,24848,24849],{"class":102},"    Archived",[92,24851,24852],{"class":134},"               // 2\n",[92,24854,24855],{"class":94,"line":161},[92,24856,24307],{"class":119},[92,24858,24859],{"class":94,"line":166},[92,24860,110],{"emptyLinePlaceholder":109},[92,24862,24863,24865,24868,24870,24872],{"class":94,"line":187},[92,24864,816],{"class":98},[92,24866,24867],{"class":102}," MaxRetries",[92,24869,853],{"class":98},[92,24871,856],{"class":102},[92,24873,24874],{"class":134},"          // untyped constant, adapts to context\n",[39,24876,1155],{"id":1154},[11,24878,24879],{},"Go's operators are conventional, with a few pointed differences from other languages worth flagging up front:",[11016,24881,24882,24902,24912,24919,24930],{},[11019,24883,24884,24885,24888,24889,24891,24892,24894,24895,24897,24898,24901],{},"Arithmetic: ",[15,24886,24887],{},"+ - * / %",", where ",[15,24890,529],{}," on two integers truncates toward zero and ",[15,24893,1178],{}," is integer remainder. There is no ",[15,24896,1165],{}," operator; use ",[15,24899,24900],{},"math.Pow"," for exponentiation.",[11019,24903,24904,24905,24908,24909,24911],{},"Comparison: ",[15,24906,24907],{},"== != \u003C \u003C= > >=",". Two structs are comparable with ",[15,24910,1344],{}," if all their fields are comparable, which is convenient and has no equivalent in most languages.",[11019,24913,24914,24915,24918],{},"Logical: ",[15,24916,24917],{},"&& || !",", with short-circuit evaluation.",[11019,24920,24921,24922,24925,24926,24929],{},"Bitwise: ",[15,24923,24924],{},"& | ^ \u003C\u003C >>"," plus ",[15,24927,24928],{},"&^",", the \"AND NOT\" (bit clear) operator that is unusual to Go.",[11019,24931,24932,24933,195,24935,24937,24938,195,24940,24942],{},"Assignment: ",[15,24934,126],{},[15,24936,24335],{},", and the compound forms ",[15,24939,1182],{},[15,24941,1185],{},", and so on.",[11,24944,24945,24946,24949,24950,529,24952,24954,24955,834,24958,24961,24962,24965,24966,6339,24969,81],{},"Two things routinely trip people up. First, Go has ",[10490,24947,24948],{},"no ternary operator",", so a conditional value needs a full ",[15,24951,4588],{},[15,24953,4594],{},". Second, ",[15,24956,24957],{},"x++",[15,24959,24960],{},"x--"," are ",[1511,24963,24964],{},"statements",", not expressions, so you cannot write ",[15,24967,24968],{},"y := x++",[15,24970,24971],{},"arr[x++]",[83,24973,24975],{"className":24256,"code":24974,"language":24258,"meta":88,"style":88},"7 / 2        // 3   (integer division truncates)\n7 % 2        // 1\n1 \u003C\u003C 4       // 16  (left shift)\n0b1100 &^ 0b0100 // 8: clears the bits set in the right operand\n\ncount++      // a statement on its own line, never inside an expression\n",[15,24976,24977,24988,24999,25010,25030,25034],{"__ignoreMap":88},[92,24978,24979,24981,24983,24985],{"class":94,"line":95},[92,24980,1205],{"class":102},[92,24982,1222],{"class":98},[92,24984,1225],{"class":102},[92,24986,24987],{"class":134},"        // 3   (integer division truncates)\n",[92,24989,24990,24992,24994,24996],{"class":94,"line":106},[92,24991,1205],{"class":102},[92,24993,1269],{"class":98},[92,24995,1225],{"class":102},[92,24997,24998],{"class":134},"        // 1\n",[92,25000,25001,25003,25005,25007],{"class":94,"line":113},[92,25002,68],{"class":102},[92,25004,1923],{"class":98},[92,25006,1926],{"class":102},[92,25008,25009],{"class":134},"       // 16  (left shift)\n",[92,25011,25012,25015,25018,25021,25024,25027],{"class":94,"line":138},[92,25013,25014],{"class":98},"0b",[92,25016,25017],{"class":102},"1100",[92,25019,25020],{"class":98}," &^",[92,25022,25023],{"class":98}," 0b",[92,25025,25026],{"class":102},"0100",[92,25028,25029],{"class":134}," // 8: clears the bits set in the right operand\n",[92,25031,25032],{"class":94,"line":143},[92,25033,110],{"emptyLinePlaceholder":109},[92,25035,25036,25038,25040],{"class":94,"line":149},[92,25037,3243],{"class":119},[92,25039,4926],{"class":98},[92,25041,25042],{"class":134},"      // a statement on its own line, never inside an expression\n",[39,25044,25046],{"id":25045},"strings-bytes-and-runes","Strings, Bytes, and Runes",[242,25048,25050],{"id":25049},"strings-are-immutable-utf-8-bytes","Strings are immutable UTF-8 bytes",[11,25052,25053,25054,25057,25058,25060,25061,25064,25065,25067],{},"A Go string is a read-only slice of bytes holding UTF-8 text, so indexing with ",[15,25055,25056],{},"s[i]"," gives you a single ",[1511,25059,24607],{},", not a character, and ",[15,25062,25063],{},"len(s)"," returns the number of bytes. To iterate over actual characters (runes), use ",[15,25066,3942],{},", which decodes one UTF-8 code point per step and gives you its starting byte index. This distinction is the source of most string bugs when the text is not plain ASCII.",[83,25069,25071],{"className":24256,"code":25070,"language":24258,"meta":88,"style":88},"s := \"héllo\"\nlen(s)        // 6, not 5: 'é' takes two bytes in UTF-8\ns[0]          // 104, the byte value of 'h' (a byte, not \"h\")\n\nfor i, r := range s {         // r is a rune (int32), i is the byte offset\n    fmt.Printf(\"%d:%c \", i, r) // 0:h 1:é 3:l 4:l 5:o\n}\n\nutf8.RuneCountInString(s)     // 5: the real character count\n",[15,25072,25073,25082,25093,25106,25110,25128,25155,25159,25163],{"__ignoreMap":88},[92,25074,25075,25077,25079],{"class":94,"line":95},[92,25076,24723],{"class":119},[92,25078,24335],{"class":98},[92,25080,25081],{"class":171}," \"héllo\"\n",[92,25083,25084,25087,25090],{"class":94,"line":106},[92,25085,25086],{"class":5161},"len",[92,25088,25089],{"class":119},"(s)        ",[92,25091,25092],{"class":134},"// 6, not 5: 'é' takes two bytes in UTF-8\n",[92,25094,25095,25098,25100,25103],{"class":94,"line":113},[92,25096,25097],{"class":119},"s[",[92,25099,554],{"class":102},[92,25101,25102],{"class":119},"]          ",[92,25104,25105],{"class":134},"// 104, the byte value of 'h' (a byte, not \"h\")\n",[92,25107,25108],{"class":94,"line":138},[92,25109,110],{"emptyLinePlaceholder":109},[92,25111,25112,25114,25117,25119,25122,25125],{"class":94,"line":143},[92,25113,4906],{"class":98},[92,25115,25116],{"class":119}," i, r ",[92,25118,24335],{"class":98},[92,25120,25121],{"class":98}," range",[92,25123,25124],{"class":119}," s {         ",[92,25126,25127],{"class":134},"// r is a rune (int32), i is the byte offset\n",[92,25129,25130,25132,25135,25137,25139,25142,25144,25147,25149,25152],{"class":94,"line":149},[92,25131,24353],{"class":119},[92,25133,25134],{"class":5161},"Printf",[92,25136,120],{"class":119},[92,25138,178],{"class":171},[92,25140,25141],{"class":102},"%d",[92,25143,5185],{"class":171},[92,25145,25146],{"class":102},"%c",[92,25148,5198],{"class":171},[92,25150,25151],{"class":119},", i, r) ",[92,25153,25154],{"class":134},"// 0:h 1:é 3:l 4:l 5:o\n",[92,25156,25157],{"class":94,"line":155},[92,25158,4711],{"class":119},[92,25160,25161],{"class":94,"line":161},[92,25162,110],{"emptyLinePlaceholder":109},[92,25164,25165,25168,25171,25174],{"class":94,"line":166},[92,25166,25167],{"class":119},"utf8.",[92,25169,25170],{"class":5161},"RuneCountInString",[92,25172,25173],{"class":119},"(s)     ",[92,25175,25176],{"class":134},"// 5: the real character count\n",[242,25178,25180],{"id":25179},"raw-strings-and-conversions","Raw strings and conversions",[11,25182,25183,25184,25187,25188,25190,25191,25194],{},"Backtick-delimited ",[1511,25185,25186],{},"raw"," string literals span multiple lines and ignore escape sequences, which is ideal for regexes, JSON blobs, and templates. Because strings are immutable, building one up character by character with ",[15,25189,1795],{}," reallocates every time; use ",[15,25192,25193],{},"strings.Builder"," in a loop to avoid that cost.",[83,25196,25198],{"className":24256,"code":25197,"language":24258,"meta":88,"style":88},"raw := `C:\\path\\no\\escapes\nspanning multiple lines`     // no \\n processing, no escaping needed\n\nvar b strings.Builder\nfor i := 0; i \u003C 3; i++ {\n    b.WriteString(\"go\")      // efficient: no per-iteration reallocation\n}\nb.String()                   // \"gogogo\"\n",[15,25199,25200,25210,25218,25222,25236,25261,25280,25284],{"__ignoreMap":88},[92,25201,25202,25205,25207],{"class":94,"line":95},[92,25203,25204],{"class":119},"raw ",[92,25206,24335],{"class":98},[92,25208,25209],{"class":171}," `C:\\path\\no\\escapes\n",[92,25211,25212,25215],{"class":94,"line":106},[92,25213,25214],{"class":171},"spanning multiple lines`",[92,25216,25217],{"class":134},"     // no \\n processing, no escaping needed\n",[92,25219,25220],{"class":94,"line":113},[92,25221,110],{"emptyLinePlaceholder":109},[92,25223,25224,25226,25229,25231,25233],{"class":94,"line":138},[92,25225,24414],{"class":98},[92,25227,25228],{"class":119}," b ",[92,25230,1975],{"class":5161},[92,25232,81],{"class":119},[92,25234,25235],{"class":5161},"Builder\n",[92,25237,25238,25240,25243,25245,25247,25250,25252,25254,25257,25259],{"class":94,"line":143},[92,25239,4906],{"class":98},[92,25241,25242],{"class":119}," i ",[92,25244,24335],{"class":98},[92,25246,331],{"class":102},[92,25248,25249],{"class":119},"; i ",[92,25251,4671],{"class":98},[92,25253,856],{"class":102},[92,25255,25256],{"class":119},"; i",[92,25258,4926],{"class":98},[92,25260,4695],{"class":119},[92,25262,25263,25266,25269,25271,25274,25277],{"class":94,"line":149},[92,25264,25265],{"class":119},"    b.",[92,25267,25268],{"class":5161},"WriteString",[92,25270,120],{"class":119},[92,25272,25273],{"class":171},"\"go\"",[92,25275,25276],{"class":119},")      ",[92,25278,25279],{"class":134},"// efficient: no per-iteration reallocation\n",[92,25281,25282],{"class":94,"line":155},[92,25283,4711],{"class":119},[92,25285,25286,25289,25292,25295],{"class":94,"line":161},[92,25287,25288],{"class":119},"b.",[92,25290,25291],{"class":5161},"String",[92,25293,25294],{"class":119},"()                   ",[92,25296,25297],{"class":134},"// \"gogogo\"\n",[242,25299,25301],{"id":25300},"the-strings-and-strconv-packages","The strings and strconv packages",[11,25303,25304,25305,25307,25308,81],{},"String operations live in the ",[15,25306,1975],{}," package (there are no string methods), and conversions between strings and numbers live in ",[15,25309,25310],{},"strconv",[83,25312,25314],{"className":24256,"code":25313,"language":24258,"meta":88,"style":88},"strings.Contains(\"seafood\", \"foo\")   // true\nstrings.HasPrefix(\"golang\", \"go\")    // true\nstrings.Index(\"chicken\", \"ken\")      // 4 (-1 if absent)\nstrings.Split(\"a,b,c\", \",\")          // [\"a\", \"b\", \"c\"]\nstrings.Join([]string{\"a\", \"b\"}, \"-\")// \"a-b\"\nstrings.ReplaceAll(\"aaa\", \"a\", \"b\")  // \"bbb\"\nstrings.ToUpper(\"hi\")                // \"HI\"\nstrings.TrimSpace(\"  hi  \")          // \"hi\"\nstrings.Fields(\"  a  b   c \")        // [\"a\", \"b\", \"c\"] (split on any whitespace)\nstrings.Repeat(\"ab\", 3)              // \"ababab\"\n\nstrconv.Atoi(\"42\")                   // 42, nil   (string to int, returns an error)\nstrconv.Itoa(42)                     // \"42\"\nstrconv.ParseInt(\"ff\", 16, 64)       // 255, nil  (base 16)\nstrconv.ParseFloat(\"3.14\", 64)       // 3.14, nil\nstrconv.FormatInt(255, 16)           // \"ff\"\n",[15,25315,25316,25339,25359,25381,25404,25438,25464,25480,25497,25515,25537,25541,25560,25577,25604,25625],{"__ignoreMap":88},[92,25317,25318,25321,25324,25326,25329,25331,25334,25337],{"class":94,"line":95},[92,25319,25320],{"class":119},"strings.",[92,25322,25323],{"class":5161},"Contains",[92,25325,120],{"class":119},[92,25327,25328],{"class":171},"\"seafood\"",[92,25330,195],{"class":119},[92,25332,25333],{"class":171},"\"foo\"",[92,25335,25336],{"class":119},")   ",[92,25338,574],{"class":134},[92,25340,25341,25343,25346,25348,25351,25353,25355,25357],{"class":94,"line":106},[92,25342,25320],{"class":119},[92,25344,25345],{"class":5161},"HasPrefix",[92,25347,120],{"class":119},[92,25349,25350],{"class":171},"\"golang\"",[92,25352,195],{"class":119},[92,25354,25273],{"class":171},[92,25356,24715],{"class":119},[92,25358,574],{"class":134},[92,25360,25361,25363,25366,25368,25371,25373,25376,25378],{"class":94,"line":113},[92,25362,25320],{"class":119},[92,25364,25365],{"class":5161},"Index",[92,25367,120],{"class":119},[92,25369,25370],{"class":171},"\"chicken\"",[92,25372,195],{"class":119},[92,25374,25375],{"class":171},"\"ken\"",[92,25377,25276],{"class":119},[92,25379,25380],{"class":134},"// 4 (-1 if absent)\n",[92,25382,25383,25385,25388,25390,25393,25395,25398,25401],{"class":94,"line":138},[92,25384,25320],{"class":119},[92,25386,25387],{"class":5161},"Split",[92,25389,120],{"class":119},[92,25391,25392],{"class":171},"\"a,b,c\"",[92,25394,195],{"class":119},[92,25396,25397],{"class":171},"\",\"",[92,25399,25400],{"class":119},")          ",[92,25402,25403],{"class":134},"// [\"a\", \"b\", \"c\"]\n",[92,25405,25406,25408,25411,25414,25416,25419,25422,25424,25427,25430,25433,25435],{"class":94,"line":143},[92,25407,25320],{"class":119},[92,25409,25410],{"class":5161},"Join",[92,25412,25413],{"class":119},"([]",[92,25415,376],{"class":98},[92,25417,25418],{"class":119},"{",[92,25420,25421],{"class":171},"\"a\"",[92,25423,195],{"class":119},[92,25425,25426],{"class":171},"\"b\"",[92,25428,25429],{"class":119},"}, ",[92,25431,25432],{"class":171},"\"-\"",[92,25434,5182],{"class":119},[92,25436,25437],{"class":134},"// \"a-b\"\n",[92,25439,25440,25442,25445,25447,25450,25452,25454,25456,25458,25461],{"class":94,"line":149},[92,25441,25320],{"class":119},[92,25443,25444],{"class":5161},"ReplaceAll",[92,25446,120],{"class":119},[92,25448,25449],{"class":171},"\"aaa\"",[92,25451,195],{"class":119},[92,25453,25421],{"class":171},[92,25455,195],{"class":119},[92,25457,25426],{"class":171},[92,25459,25460],{"class":119},")  ",[92,25462,25463],{"class":134},"// \"bbb\"\n",[92,25465,25466,25468,25470,25472,25474,25477],{"class":94,"line":155},[92,25467,25320],{"class":119},[92,25469,24341],{"class":5161},[92,25471,120],{"class":119},[92,25473,24712],{"class":171},[92,25475,25476],{"class":119},")                ",[92,25478,25479],{"class":134},"// \"HI\"\n",[92,25481,25482,25484,25487,25489,25492,25494],{"class":94,"line":161},[92,25483,25320],{"class":119},[92,25485,25486],{"class":5161},"TrimSpace",[92,25488,120],{"class":119},[92,25490,25491],{"class":171},"\"  hi  \"",[92,25493,25400],{"class":119},[92,25495,25496],{"class":134},"// \"hi\"\n",[92,25498,25499,25501,25504,25506,25509,25512],{"class":94,"line":166},[92,25500,25320],{"class":119},[92,25502,25503],{"class":5161},"Fields",[92,25505,120],{"class":119},[92,25507,25508],{"class":171},"\"  a  b   c \"",[92,25510,25511],{"class":119},")        ",[92,25513,25514],{"class":134},"// [\"a\", \"b\", \"c\"] (split on any whitespace)\n",[92,25516,25517,25519,25522,25524,25527,25529,25531,25534],{"class":94,"line":187},[92,25518,25320],{"class":119},[92,25520,25521],{"class":5161},"Repeat",[92,25523,120],{"class":119},[92,25525,25526],{"class":171},"\"ab\"",[92,25528,195],{"class":119},[92,25530,1448],{"class":102},[92,25532,25533],{"class":119},")              ",[92,25535,25536],{"class":134},"// \"ababab\"\n",[92,25538,25539],{"class":94,"line":217},[92,25540,110],{"emptyLinePlaceholder":109},[92,25542,25543,25546,25549,25551,25554,25557],{"class":94,"line":712},[92,25544,25545],{"class":119},"strconv.",[92,25547,25548],{"class":5161},"Atoi",[92,25550,120],{"class":119},[92,25552,25553],{"class":171},"\"42\"",[92,25555,25556],{"class":119},")                   ",[92,25558,25559],{"class":134},"// 42, nil   (string to int, returns an error)\n",[92,25561,25562,25564,25567,25569,25571,25574],{"class":94,"line":730},[92,25563,25545],{"class":119},[92,25565,25566],{"class":5161},"Itoa",[92,25568,120],{"class":119},[92,25570,430],{"class":102},[92,25572,25573],{"class":119},")                     ",[92,25575,25576],{"class":134},"// \"42\"\n",[92,25578,25579,25581,25584,25586,25589,25591,25593,25595,25598,25601],{"class":94,"line":747},[92,25580,25545],{"class":119},[92,25582,25583],{"class":5161},"ParseInt",[92,25585,120],{"class":119},[92,25587,25588],{"class":171},"\"ff\"",[92,25590,195],{"class":119},[92,25592,797],{"class":102},[92,25594,195],{"class":119},[92,25596,25597],{"class":102},"64",[92,25599,25600],{"class":119},")       ",[92,25602,25603],{"class":134},"// 255, nil  (base 16)\n",[92,25605,25606,25608,25611,25613,25616,25618,25620,25622],{"class":94,"line":763},[92,25607,25545],{"class":119},[92,25609,25610],{"class":5161},"ParseFloat",[92,25612,120],{"class":119},[92,25614,25615],{"class":171},"\"3.14\"",[92,25617,195],{"class":119},[92,25619,25597],{"class":102},[92,25621,25600],{"class":119},[92,25623,25624],{"class":134},"// 3.14, nil\n",[92,25626,25627,25629,25632,25634,25637,25639,25641,25644],{"class":94,"line":780},[92,25628,25545],{"class":119},[92,25630,25631],{"class":5161},"FormatInt",[92,25633,120],{"class":119},[92,25635,25636],{"class":102},"255",[92,25638,195],{"class":119},[92,25640,797],{"class":102},[92,25642,25643],{"class":119},")           ",[92,25645,25646],{"class":134},"// \"ff\"\n",[11,25648,25649,25650,1369,25653,25656,25657,25660],{},"The trap to remember: ",[15,25651,25652],{},"strconv.Atoi",[1511,25654,25655],{},"two"," values, the number and an error, so you must handle the error rather than ignore it, which is how Go signals that ",[15,25658,25659],{},"\"abc\""," is not a valid integer.",[39,25662,25664],{"id":25663},"arrays-slices-and-maps","Arrays, Slices, and Maps",[242,25666,25668],{"id":25667},"arrays-versus-slices","Arrays versus slices",[11,25670,25671,25672,834,25675,25678,25679,25682],{},"Go has both fixed-size arrays and dynamically-sized slices, and in practice you almost always use slices. An array's length is part of its type (",[15,25673,25674],{},"[3]int",[15,25676,25677],{},"[4]int"," are different types) and assigning or passing an array ",[1511,25680,25681],{},"copies"," it, which is why arrays are rare. A slice is a lightweight view into an underlying array, so it is cheap to pass around and is what every collection API expects.",[83,25684,25686],{"className":24256,"code":25685,"language":24258,"meta":88,"style":88},"var arr [3]int          // a fixed array of 3 ints, all zero: [0 0 0]\narr[0] = 1\n\ns := []int{1, 2, 3}     // a slice literal (note: no size in the brackets)\ns = append(s, 4)        // grow it; append returns a new slice header\nfirst3 := s[0:3]        // slicing: elements 0, 1, 2 (half-open range)\n",[15,25687,25688,25705,25719,25723,25751,25770],{"__ignoreMap":88},[92,25689,25690,25692,25695,25697,25700,25702],{"class":94,"line":95},[92,25691,24414],{"class":98},[92,25693,25694],{"class":119}," arr [",[92,25696,1448],{"class":102},[92,25698,25699],{"class":119},"]",[92,25701,370],{"class":98},[92,25703,25704],{"class":134},"          // a fixed array of 3 ints, all zero: [0 0 0]\n",[92,25706,25707,25710,25712,25714,25716],{"class":94,"line":106},[92,25708,25709],{"class":119},"arr[",[92,25711,554],{"class":102},[92,25713,1751],{"class":119},[92,25715,126],{"class":98},[92,25717,25718],{"class":102}," 1\n",[92,25720,25721],{"class":94,"line":113},[92,25722,110],{"emptyLinePlaceholder":109},[92,25724,25725,25727,25729,25731,25733,25735,25737,25739,25741,25743,25745,25748],{"class":94,"line":138},[92,25726,24723],{"class":119},[92,25728,24335],{"class":98},[92,25730,24705],{"class":119},[92,25732,370],{"class":98},[92,25734,25418],{"class":119},[92,25736,68],{"class":102},[92,25738,195],{"class":119},[92,25740,354],{"class":102},[92,25742,195],{"class":119},[92,25744,1448],{"class":102},[92,25746,25747],{"class":119},"}     ",[92,25749,25750],{"class":134},"// a slice literal (note: no size in the brackets)\n",[92,25752,25753,25755,25757,25760,25763,25765,25767],{"class":94,"line":143},[92,25754,24723],{"class":119},[92,25756,126],{"class":98},[92,25758,25759],{"class":5161}," append",[92,25761,25762],{"class":119},"(s, ",[92,25764,3621],{"class":102},[92,25766,25511],{"class":119},[92,25768,25769],{"class":134},"// grow it; append returns a new slice header\n",[92,25771,25772,25775,25777,25780,25782,25784,25786,25789],{"class":94,"line":149},[92,25773,25774],{"class":119},"first3 ",[92,25776,24335],{"class":98},[92,25778,25779],{"class":119}," s[",[92,25781,554],{"class":102},[92,25783,5185],{"class":119},[92,25785,1448],{"class":102},[92,25787,25788],{"class":119},"]        ",[92,25790,25791],{"class":134},"// slicing: elements 0, 1, 2 (half-open range)\n",[242,25793,25795],{"id":25794},"how-slices-actually-work","How slices actually work",[11,25797,25798],{},"A slice is a small three-field header: a pointer to a backing array, a length (how many elements are in view), and a capacity (how many the backing array can hold from the pointer onward). Understanding this explains every slice surprise:",[11016,25800,25801,25810,25820,25829],{},[11019,25802,25803,25805,25806,25809],{},[15,25804,25063],{}," is the number of usable elements; ",[15,25807,25808],{},"cap(s)"," is how far it can grow before reallocating.",[11019,25811,25812,25815,25816,25819],{},[15,25813,25814],{},"append"," writes into spare capacity if there is room, mutating the shared backing array in place; when there is no room, it allocates a ",[1511,25817,25818],{},"new, larger"," array and copies, so the original and the result no longer share memory.",[11019,25821,25822,25823,25825,25826,81],{},"Because ",[15,25824,25814],{}," may or may not reallocate, you must always assign its result back: ",[15,25827,25828],{},"s = append(s, x)",[11019,25830,25831],{},"Two slices created from the same array share elements, so writing through one is visible through the other until one of them reallocates.",[11,25833,25834],{},[3108,25835],{"alt":25836,"src":25837},"A Go slice header of pointer, length, and capacity viewing into a backing array","/post-images/go-syntax-recap/go-slice-header.png",[242,25839,25841],{"id":25840},"working-with-slices","Working with slices",[83,25843,25845],{"className":24256,"code":25844,"language":24258,"meta":88,"style":88},"s := make([]int, 3, 10)   // len 3, cap 10; the 3 elements are zero\nlen(s)                    // 3\ncap(s)                    // 10\n\ns = append(s, 1, 2)       // append several at once\ns = append(s, other...)   // spread another slice with ...\n\ndst := make([]int, len(src))\ncopy(dst, src)            // copy element-by-element into an existing slice\n\n// Remove index i (order not preserved cheaply):\ns = append(s[:i], s[i+1:]...)\n\n// A nil slice is a valid empty slice: len 0, and append works on it.\nvar empty []int\nempty = append(empty, 1)  // fine, no make() needed\n",[15,25846,25847,25873,25882,25891,25895,25916,25934,25938,25958,25969,25973,25978,26000,26004,26009,26019],{"__ignoreMap":88},[92,25848,25849,25851,25853,25856,25858,25860,25862,25864,25866,25868,25870],{"class":94,"line":95},[92,25850,24723],{"class":119},[92,25852,24335],{"class":98},[92,25854,25855],{"class":5161}," make",[92,25857,25413],{"class":119},[92,25859,370],{"class":98},[92,25861,195],{"class":119},[92,25863,1448],{"class":102},[92,25865,195],{"class":119},[92,25867,4419],{"class":102},[92,25869,25336],{"class":119},[92,25871,25872],{"class":134},"// len 3, cap 10; the 3 elements are zero\n",[92,25874,25875,25877,25880],{"class":94,"line":106},[92,25876,25086],{"class":5161},[92,25878,25879],{"class":119},"(s)                    ",[92,25881,9560],{"class":134},[92,25883,25884,25887,25889],{"class":94,"line":113},[92,25885,25886],{"class":5161},"cap",[92,25888,25879],{"class":119},[92,25890,1215],{"class":134},[92,25892,25893],{"class":94,"line":138},[92,25894,110],{"emptyLinePlaceholder":109},[92,25896,25897,25899,25901,25903,25905,25907,25909,25911,25913],{"class":94,"line":143},[92,25898,24723],{"class":119},[92,25900,126],{"class":98},[92,25902,25759],{"class":5161},[92,25904,25762],{"class":119},[92,25906,68],{"class":102},[92,25908,195],{"class":119},[92,25910,354],{"class":102},[92,25912,25600],{"class":119},[92,25914,25915],{"class":134},"// append several at once\n",[92,25917,25918,25920,25922,25924,25927,25929,25931],{"class":94,"line":149},[92,25919,24723],{"class":119},[92,25921,126],{"class":98},[92,25923,25759],{"class":5161},[92,25925,25926],{"class":119},"(s, other",[92,25928,5335],{"class":98},[92,25930,25336],{"class":119},[92,25932,25933],{"class":134},"// spread another slice with ...\n",[92,25935,25936],{"class":94,"line":155},[92,25937,110],{"emptyLinePlaceholder":109},[92,25939,25940,25943,25945,25947,25949,25951,25953,25955],{"class":94,"line":161},[92,25941,25942],{"class":119},"dst ",[92,25944,24335],{"class":98},[92,25946,25855],{"class":5161},[92,25948,25413],{"class":119},[92,25950,370],{"class":98},[92,25952,195],{"class":119},[92,25954,25086],{"class":5161},[92,25956,25957],{"class":119},"(src))\n",[92,25959,25960,25963,25966],{"class":94,"line":166},[92,25961,25962],{"class":5161},"copy",[92,25964,25965],{"class":119},"(dst, src)            ",[92,25967,25968],{"class":134},"// copy element-by-element into an existing slice\n",[92,25970,25971],{"class":94,"line":187},[92,25972,110],{"emptyLinePlaceholder":109},[92,25974,25975],{"class":94,"line":217},[92,25976,25977],{"class":134},"// Remove index i (order not preserved cheaply):\n",[92,25979,25980,25982,25984,25986,25989,25991,25993,25996,25998],{"class":94,"line":712},[92,25981,24723],{"class":119},[92,25983,126],{"class":98},[92,25985,25759],{"class":5161},[92,25987,25988],{"class":119},"(s[:i], s[i",[92,25990,1795],{"class":98},[92,25992,68],{"class":102},[92,25994,25995],{"class":119},":]",[92,25997,5335],{"class":98},[92,25999,24307],{"class":119},[92,26001,26002],{"class":94,"line":730},[92,26003,110],{"emptyLinePlaceholder":109},[92,26005,26006],{"class":94,"line":747},[92,26007,26008],{"class":134},"// A nil slice is a valid empty slice: len 0, and append works on it.\n",[92,26010,26011,26013,26016],{"class":94,"line":763},[92,26012,24414],{"class":98},[92,26014,26015],{"class":119}," empty []",[92,26017,26018],{"class":98},"int\n",[92,26020,26021,26024,26026,26028,26031,26033,26035],{"class":94,"line":780},[92,26022,26023],{"class":119},"empty ",[92,26025,126],{"class":98},[92,26027,25759],{"class":5161},[92,26029,26030],{"class":119},"(empty, ",[92,26032,68],{"class":102},[92,26034,25460],{"class":119},[92,26036,26037],{"class":134},"// fine, no make() needed\n",[242,26039,26041],{"id":26040},"two-dimensional-slices","Two-dimensional slices",[11,26043,26044],{},"Go has no built-in 2D slice, so you build a slice of slices, allocating each row. This matters in grid problems, where forgetting to allocate the inner rows gives you a nil-slice panic on write.",[83,26046,26048],{"className":24256,"code":26047,"language":24258,"meta":88,"style":88},"rows, cols := 3, 4\ngrid := make([][]int, rows)\nfor i := range grid {\n    grid[i] = make([]int, cols) // each row must be allocated\n}\ngrid[2][3] = 9\n",[15,26049,26050,26064,26081,26094,26113,26117],{"__ignoreMap":88},[92,26051,26052,26055,26057,26059,26061],{"class":94,"line":95},[92,26053,26054],{"class":119},"rows, cols ",[92,26056,24335],{"class":98},[92,26058,856],{"class":102},[92,26060,195],{"class":119},[92,26062,26063],{"class":102},"4\n",[92,26065,26066,26069,26071,26073,26076,26078],{"class":94,"line":106},[92,26067,26068],{"class":119},"grid ",[92,26070,24335],{"class":98},[92,26072,25855],{"class":5161},[92,26074,26075],{"class":119},"([][]",[92,26077,370],{"class":98},[92,26079,26080],{"class":119},", rows)\n",[92,26082,26083,26085,26087,26089,26091],{"class":94,"line":113},[92,26084,4906],{"class":98},[92,26086,25242],{"class":119},[92,26088,24335],{"class":98},[92,26090,25121],{"class":98},[92,26092,26093],{"class":119}," grid {\n",[92,26095,26096,26099,26101,26103,26105,26107,26110],{"class":94,"line":138},[92,26097,26098],{"class":119},"    grid[i] ",[92,26100,126],{"class":98},[92,26102,25855],{"class":5161},[92,26104,25413],{"class":119},[92,26106,370],{"class":98},[92,26108,26109],{"class":119},", cols) ",[92,26111,26112],{"class":134},"// each row must be allocated\n",[92,26114,26115],{"class":94,"line":143},[92,26116,4711],{"class":119},[92,26118,26119,26122,26124,26126,26128,26130,26132],{"class":94,"line":149},[92,26120,26121],{"class":119},"grid[",[92,26123,354],{"class":102},[92,26125,3097],{"class":119},[92,26127,1448],{"class":102},[92,26129,1751],{"class":119},[92,26131,126],{"class":98},[92,26133,26134],{"class":102}," 9\n",[242,26136,26138],{"id":26137},"maps","Maps",[11,26140,26141,26142,26145,26146,26149],{},"A map is Go's hash table, written ",[15,26143,26144],{},"map[Key]Value",". You create one with ",[15,26147,26148],{},"make"," or a literal, and reading a missing key returns the value's zero value rather than an error, so Go gives you the \"comma ok\" form to tell \"missing\" apart from \"present but zero.\" Iteration order is deliberately randomized, so never rely on it.",[83,26151,26153],{"className":24256,"code":26152,"language":24258,"meta":88,"style":88},"m := map[string]int{\"ada\": 90, \"lin\": 70}\nm[\"joy\"] = 85            // insert or update\nscore := m[\"ada\"]        // 90\nmissing := m[\"nobody\"]   // 0, the zero value (no error)\n\nv, ok := m[\"joy\"]        // comma-ok: v is 85, ok is true\n_, exists := m[\"nobody\"] // exists is false\n\ndelete(m, \"lin\")         // remove a key\nlen(m)                   // number of entries\n\nfor key, val := range m { // NOTE: iteration order is random each run\n    _ = key; _ = val\n}\n",[15,26154,26155,26195,26212,26229,26247,26251,26267,26283,26287,26303,26313,26317,26334,26349],{"__ignoreMap":88},[92,26156,26157,26160,26162,26165,26167,26169,26171,26173,26175,26178,26180,26183,26185,26188,26190,26193],{"class":94,"line":95},[92,26158,26159],{"class":119},"m ",[92,26161,24335],{"class":98},[92,26163,26164],{"class":98}," map",[92,26166,1841],{"class":119},[92,26168,376],{"class":98},[92,26170,25699],{"class":119},[92,26172,370],{"class":98},[92,26174,25418],{"class":119},[92,26176,26177],{"class":171},"\"ada\"",[92,26179,5263],{"class":119},[92,26181,26182],{"class":102},"90",[92,26184,195],{"class":119},[92,26186,26187],{"class":171},"\"lin\"",[92,26189,5263],{"class":119},[92,26191,26192],{"class":102},"70",[92,26194,4711],{"class":119},[92,26196,26197,26200,26203,26205,26207,26209],{"class":94,"line":106},[92,26198,26199],{"class":119},"m[",[92,26201,26202],{"class":171},"\"joy\"",[92,26204,1751],{"class":119},[92,26206,126],{"class":98},[92,26208,4295],{"class":102},[92,26210,26211],{"class":134},"            // insert or update\n",[92,26213,26214,26217,26219,26222,26224,26226],{"class":94,"line":113},[92,26215,26216],{"class":119},"score ",[92,26218,24335],{"class":98},[92,26220,26221],{"class":119}," m[",[92,26223,26177],{"class":171},[92,26225,25788],{"class":119},[92,26227,26228],{"class":134},"// 90\n",[92,26230,26231,26234,26236,26238,26241,26244],{"class":94,"line":138},[92,26232,26233],{"class":119},"missing ",[92,26235,24335],{"class":98},[92,26237,26221],{"class":119},[92,26239,26240],{"class":171},"\"nobody\"",[92,26242,26243],{"class":119},"]   ",[92,26245,26246],{"class":134},"// 0, the zero value (no error)\n",[92,26248,26249],{"class":94,"line":143},[92,26250,110],{"emptyLinePlaceholder":109},[92,26252,26253,26256,26258,26260,26262,26264],{"class":94,"line":149},[92,26254,26255],{"class":119},"v, ok ",[92,26257,24335],{"class":98},[92,26259,26221],{"class":119},[92,26261,26202],{"class":171},[92,26263,25788],{"class":119},[92,26265,26266],{"class":134},"// comma-ok: v is 85, ok is true\n",[92,26268,26269,26272,26274,26276,26278,26280],{"class":94,"line":155},[92,26270,26271],{"class":119},"_, exists ",[92,26273,24335],{"class":98},[92,26275,26221],{"class":119},[92,26277,26240],{"class":171},[92,26279,1751],{"class":119},[92,26281,26282],{"class":134},"// exists is false\n",[92,26284,26285],{"class":94,"line":161},[92,26286,110],{"emptyLinePlaceholder":109},[92,26288,26289,26292,26295,26297,26300],{"class":94,"line":166},[92,26290,26291],{"class":5161},"delete",[92,26293,26294],{"class":119},"(m, ",[92,26296,26187],{"class":171},[92,26298,26299],{"class":119},")         ",[92,26301,26302],{"class":134},"// remove a key\n",[92,26304,26305,26307,26310],{"class":94,"line":187},[92,26306,25086],{"class":5161},[92,26308,26309],{"class":119},"(m)                   ",[92,26311,26312],{"class":134},"// number of entries\n",[92,26314,26315],{"class":94,"line":217},[92,26316,110],{"emptyLinePlaceholder":109},[92,26318,26319,26321,26324,26326,26328,26331],{"class":94,"line":712},[92,26320,4906],{"class":98},[92,26322,26323],{"class":119}," key, val ",[92,26325,24335],{"class":98},[92,26327,25121],{"class":98},[92,26329,26330],{"class":119}," m { ",[92,26332,26333],{"class":134},"// NOTE: iteration order is random each run\n",[92,26335,26336,26339,26341,26344,26346],{"class":94,"line":730},[92,26337,26338],{"class":119},"    _ ",[92,26340,126],{"class":98},[92,26342,26343],{"class":119}," key; _ ",[92,26345,126],{"class":98},[92,26347,26348],{"class":119}," val\n",[92,26350,26351],{"class":94,"line":747},[92,26352,4711],{"class":119},[11,26354,26355,26356,26359],{},"Go has no built-in set, so the idiom is a map whose value is the empty struct ",[15,26357,26358],{},"struct{}{}",", which takes zero bytes:",[83,26361,26363],{"className":24256,"code":26362,"language":24258,"meta":88,"style":88},"seen := map[string]struct{}{}\nseen[\"a\"] = struct{}{}          // add\nif _, ok := seen[\"a\"]; ok {     // membership test\n    // present\n}\n",[15,26364,26365,26386,26406,26426,26431],{"__ignoreMap":88},[92,26366,26367,26370,26372,26374,26376,26378,26380,26383],{"class":94,"line":95},[92,26368,26369],{"class":119},"seen ",[92,26371,24335],{"class":98},[92,26373,26164],{"class":98},[92,26375,1841],{"class":119},[92,26377,376],{"class":98},[92,26379,25699],{"class":119},[92,26381,26382],{"class":98},"struct",[92,26384,26385],{"class":119},"{}{}\n",[92,26387,26388,26391,26393,26395,26397,26400,26403],{"class":94,"line":106},[92,26389,26390],{"class":119},"seen[",[92,26392,25421],{"class":171},[92,26394,1751],{"class":119},[92,26396,126],{"class":98},[92,26398,26399],{"class":98}," struct",[92,26401,26402],{"class":119},"{}{}          ",[92,26404,26405],{"class":134},"// add\n",[92,26407,26408,26410,26413,26415,26418,26420,26423],{"class":94,"line":113},[92,26409,4588],{"class":98},[92,26411,26412],{"class":119}," _, ok ",[92,26414,24335],{"class":98},[92,26416,26417],{"class":119}," seen[",[92,26419,25421],{"class":171},[92,26421,26422],{"class":119},"]; ok {     ",[92,26424,26425],{"class":134},"// membership test\n",[92,26427,26428],{"class":94,"line":138},[92,26429,26430],{"class":134},"    // present\n",[92,26432,26433],{"class":94,"line":143},[92,26434,4711],{"class":119},[242,26436,26438],{"id":26437},"the-slices-and-maps-packages","The slices and maps packages",[11,26440,26441,26442,195,26444,394,26446,26449],{},"Since Go 1.21 the standard library includes generic helpers that replace a lot of hand-written loops, plus ",[15,26443,4042],{},[15,26445,4036],{},[15,26447,26448],{},"clear"," as builtins.",[83,26451,26453],{"className":24256,"code":26452,"language":24258,"meta":88,"style":88},"slices.Sort(s)                       // sort in ascending order, in place\nslices.Contains(s, 3)                // true if 3 is present\nslices.Index(s, 3)                   // first index of 3, or -1\nslices.Max(s); slices.Min(s)         // largest / smallest element\nslices.Reverse(s)                    // reverse in place\nslices.Equal(a, b)                   // element-wise equality\n\nmin(3, 7)                            // 3 (builtin since Go 1.21)\nmax(3, 7)                            // 7\nclear(m)                             // remove all entries from a map\n",[15,26454,26455,26469,26484,26499,26518,26530,26543,26547,26565,26582],{"__ignoreMap":88},[92,26456,26457,26460,26463,26466],{"class":94,"line":95},[92,26458,26459],{"class":119},"slices.",[92,26461,26462],{"class":5161},"Sort",[92,26464,26465],{"class":119},"(s)                       ",[92,26467,26468],{"class":134},"// sort in ascending order, in place\n",[92,26470,26471,26473,26475,26477,26479,26481],{"class":94,"line":106},[92,26472,26459],{"class":119},[92,26474,25323],{"class":5161},[92,26476,25762],{"class":119},[92,26478,1448],{"class":102},[92,26480,25476],{"class":119},[92,26482,26483],{"class":134},"// true if 3 is present\n",[92,26485,26486,26488,26490,26492,26494,26496],{"class":94,"line":113},[92,26487,26459],{"class":119},[92,26489,25365],{"class":5161},[92,26491,25762],{"class":119},[92,26493,1448],{"class":102},[92,26495,25556],{"class":119},[92,26497,26498],{"class":134},"// first index of 3, or -1\n",[92,26500,26501,26503,26506,26509,26512,26515],{"class":94,"line":138},[92,26502,26459],{"class":119},[92,26504,26505],{"class":5161},"Max",[92,26507,26508],{"class":119},"(s); slices.",[92,26510,26511],{"class":5161},"Min",[92,26513,26514],{"class":119},"(s)         ",[92,26516,26517],{"class":134},"// largest / smallest element\n",[92,26519,26520,26522,26525,26527],{"class":94,"line":143},[92,26521,26459],{"class":119},[92,26523,26524],{"class":5161},"Reverse",[92,26526,25879],{"class":119},[92,26528,26529],{"class":134},"// reverse in place\n",[92,26531,26532,26534,26537,26540],{"class":94,"line":149},[92,26533,26459],{"class":119},[92,26535,26536],{"class":5161},"Equal",[92,26538,26539],{"class":119},"(a, b)                   ",[92,26541,26542],{"class":134},"// element-wise equality\n",[92,26544,26545],{"class":94,"line":155},[92,26546,110],{"emptyLinePlaceholder":109},[92,26548,26549,26551,26553,26555,26557,26559,26562],{"class":94,"line":161},[92,26550,4042],{"class":5161},[92,26552,120],{"class":119},[92,26554,1448],{"class":102},[92,26556,195],{"class":119},[92,26558,1205],{"class":102},[92,26560,26561],{"class":119},")                            ",[92,26563,26564],{"class":134},"// 3 (builtin since Go 1.21)\n",[92,26566,26567,26569,26571,26573,26575,26577,26579],{"class":94,"line":166},[92,26568,4036],{"class":5161},[92,26570,120],{"class":119},[92,26572,1448],{"class":102},[92,26574,195],{"class":119},[92,26576,1205],{"class":102},[92,26578,26561],{"class":119},[92,26580,26581],{"class":134},"// 7\n",[92,26583,26584,26586,26589],{"class":94,"line":187},[92,26585,26448],{"class":5161},[92,26587,26588],{"class":119},"(m)                             ",[92,26590,26591],{"class":134},"// remove all entries from a map\n",[11,26593,26594,26595,26598,26599,26602,26603,26606],{},"In a coding round, slices and maps cover almost everything: a ",[15,26596,26597],{},"map"," is your hash map and, with ",[15,26600,26601],{},"struct{}"," values, your set; a ",[15,26604,26605],{},"[]T"," is your dynamic array, stack (append and re-slice), and queue (though popping the front is O(n), so use a real structure for heavy queue work).",[39,26608,4579],{"id":4578},[242,26610,26612],{"id":26611},"if-and-switch","if and switch",[11,26614,26615,26616,26618,26619,26621,26622,26624,26625,26627,26628,529,26630,26632,26633,26636],{},"An ",[15,26617,4588],{}," has no parentheses around the condition and can start with a short init statement, scoped to the ",[15,26620,4588],{},", which is the idiomatic place to call a function and check its error in one line. A ",[15,26623,4606],{}," in Go does ",[1511,26626,5608],{}," fall through by default (each case breaks on its own), you can omit the condition to write a clean ",[15,26629,4588],{},[15,26631,4594],{}," chain, and a ",[1511,26634,26635],{},"type switch"," branches on the dynamic type of an interface value.",[83,26638,26640],{"className":24256,"code":26639,"language":24258,"meta":88,"style":88},"if v := compute(); v > 0 {       // init statement + condition; v is scoped here\n    fmt.Println(v)\n} else {\n    fmt.Println(\"non-positive\")\n}\n\nswitch day {\ncase \"sat\", \"sun\":               // multiple values per case\n    fmt.Println(\"weekend\")\ncase \"mon\":\n    fmt.Println(\"monday\")\n    fallthrough                  // opt in to fall through explicitly\ndefault:\n    fmt.Println(\"weekday\")\n}\n\nswitch {                         // no condition: acts like if/else-if\ncase score >= 90:\n    grade = \"A\"\ncase score >= 80:\n    grade = \"B\"\n}\n",[15,26641,26642,26666,26675,26683,26696,26700,26704,26711,26730,26743,26752,26765,26773,26779,26792,26796,26800,26810,26823,26833,26846,26855],{"__ignoreMap":88},[92,26643,26644,26646,26649,26651,26654,26657,26659,26661,26663],{"class":94,"line":95},[92,26645,4588],{"class":98},[92,26647,26648],{"class":119}," v ",[92,26650,24335],{"class":98},[92,26652,26653],{"class":5161}," compute",[92,26655,26656],{"class":119},"(); v ",[92,26658,1599],{"class":98},[92,26660,331],{"class":102},[92,26662,7254],{"class":119},[92,26664,26665],{"class":134},"// init statement + condition; v is scoped here\n",[92,26667,26668,26670,26672],{"class":94,"line":106},[92,26669,24353],{"class":119},[92,26671,24356],{"class":5161},[92,26673,26674],{"class":119},"(v)\n",[92,26676,26677,26679,26681],{"class":94,"line":113},[92,26678,4664],{"class":119},[92,26680,4594],{"class":98},[92,26682,4695],{"class":119},[92,26684,26685,26687,26689,26691,26694],{"class":94,"line":138},[92,26686,24353],{"class":119},[92,26688,24356],{"class":5161},[92,26690,120],{"class":119},[92,26692,26693],{"class":171},"\"non-positive\"",[92,26695,24307],{"class":119},[92,26697,26698],{"class":94,"line":143},[92,26699,4711],{"class":119},[92,26701,26702],{"class":94,"line":149},[92,26703,110],{"emptyLinePlaceholder":109},[92,26705,26706,26708],{"class":94,"line":155},[92,26707,4606],{"class":98},[92,26709,26710],{"class":119}," day {\n",[92,26712,26713,26716,26719,26721,26724,26727],{"class":94,"line":161},[92,26714,26715],{"class":98},"case",[92,26717,26718],{"class":171}," \"sat\"",[92,26720,195],{"class":119},[92,26722,26723],{"class":171},"\"sun\"",[92,26725,26726],{"class":119},":               ",[92,26728,26729],{"class":134},"// multiple values per case\n",[92,26731,26732,26734,26736,26738,26741],{"class":94,"line":166},[92,26733,24353],{"class":119},[92,26735,24356],{"class":5161},[92,26737,120],{"class":119},[92,26739,26740],{"class":171},"\"weekend\"",[92,26742,24307],{"class":119},[92,26744,26745,26747,26750],{"class":94,"line":187},[92,26746,26715],{"class":98},[92,26748,26749],{"class":171}," \"mon\"",[92,26751,4828],{"class":119},[92,26753,26754,26756,26758,26760,26763],{"class":94,"line":217},[92,26755,24353],{"class":119},[92,26757,24356],{"class":5161},[92,26759,120],{"class":119},[92,26761,26762],{"class":171},"\"monday\"",[92,26764,24307],{"class":119},[92,26766,26767,26770],{"class":94,"line":712},[92,26768,26769],{"class":98},"    fallthrough",[92,26771,26772],{"class":134},"                  // opt in to fall through explicitly\n",[92,26774,26775,26777],{"class":94,"line":730},[92,26776,4628],{"class":98},[92,26778,4828],{"class":119},[92,26780,26781,26783,26785,26787,26790],{"class":94,"line":747},[92,26782,24353],{"class":119},[92,26784,24356],{"class":5161},[92,26786,120],{"class":119},[92,26788,26789],{"class":171},"\"weekday\"",[92,26791,24307],{"class":119},[92,26793,26794],{"class":94,"line":763},[92,26795,4711],{"class":119},[92,26797,26798],{"class":94,"line":780},[92,26799,110],{"emptyLinePlaceholder":109},[92,26801,26802,26804,26807],{"class":94,"line":785},[92,26803,4606],{"class":98},[92,26805,26806],{"class":119}," {                         ",[92,26808,26809],{"class":134},"// no condition: acts like if/else-if\n",[92,26811,26812,26814,26817,26819,26821],{"class":94,"line":2585},[92,26813,26715],{"class":98},[92,26815,26816],{"class":119}," score ",[92,26818,1681],{"class":98},[92,26820,4275],{"class":102},[92,26822,4828],{"class":119},[92,26824,26825,26828,26830],{"class":94,"line":2605},[92,26826,26827],{"class":119},"    grade ",[92,26829,126],{"class":98},[92,26831,26832],{"class":171}," \"A\"\n",[92,26834,26835,26837,26839,26841,26844],{"class":94,"line":2634},[92,26836,26715],{"class":98},[92,26838,26816],{"class":119},[92,26840,1681],{"class":98},[92,26842,26843],{"class":102}," 80",[92,26845,4828],{"class":119},[92,26847,26848,26850,26852],{"class":94,"line":2651},[92,26849,26827],{"class":119},[92,26851,126],{"class":98},[92,26853,26854],{"class":171}," \"B\"\n",[92,26856,26857],{"class":94,"line":2671},[92,26858,4711],{"class":119},[242,26860,26862],{"id":26861},"the-for-loop","The for loop",[11,26864,26865,26866,26868],{},"Go has exactly one loop keyword, ",[15,26867,4906],{},", which covers every looping need in four shapes:",[11016,26870,26871,26877,26885,26893],{},[11019,26872,26873,26874,81],{},"Three-clause C-style: ",[15,26875,26876],{},"for i := 0; i \u003C n; i++ { }",[11019,26878,26879,26880,5263,26882,81],{},"Condition-only, which is Go's ",[15,26881,4970],{},[15,26883,26884],{},"for cond { }",[11019,26886,26887,26888,5263,26890,81],{},"No clause, an infinite loop you exit with ",[15,26889,4614],{},[15,26891,26892],{},"for { }",[11019,26894,26895,26896,81],{},"Range form over a collection: ",[15,26897,26898],{},"for i, v := range s { }",[11,26900,26901,26903],{},[15,26902,3942],{}," adapts to what you iterate, and since Go 1.22 you can even range over an integer:",[83,26905,26907],{"className":24256,"code":26906,"language":24258,"meta":88,"style":88},"for i, v := range []string{\"a\", \"b\"} { } // index and value of a slice\nfor k, v := range someMap { }            // key and value of a map (random order)\nfor i, r := range \"héllo\" { }            // byte index and rune of a string\nfor v := range ch { }                    // values from a channel until it closes\nfor i := range 5 { }                     // 0,1,2,3,4 (Go 1.22+: range over an int)\n",[15,26908,26909,26938,26955,26974,26990],{"__ignoreMap":88},[92,26910,26911,26913,26916,26918,26920,26922,26924,26926,26928,26930,26932,26935],{"class":94,"line":95},[92,26912,4906],{"class":98},[92,26914,26915],{"class":119}," i, v ",[92,26917,24335],{"class":98},[92,26919,25121],{"class":98},[92,26921,24705],{"class":119},[92,26923,376],{"class":98},[92,26925,25418],{"class":119},[92,26927,25421],{"class":171},[92,26929,195],{"class":119},[92,26931,25426],{"class":171},[92,26933,26934],{"class":119},"} { } ",[92,26936,26937],{"class":134},"// index and value of a slice\n",[92,26939,26940,26942,26945,26947,26949,26952],{"class":94,"line":106},[92,26941,4906],{"class":98},[92,26943,26944],{"class":119}," k, v ",[92,26946,24335],{"class":98},[92,26948,25121],{"class":98},[92,26950,26951],{"class":119}," someMap { }            ",[92,26953,26954],{"class":134},"// key and value of a map (random order)\n",[92,26956,26957,26959,26961,26963,26965,26968,26971],{"class":94,"line":113},[92,26958,4906],{"class":98},[92,26960,25116],{"class":119},[92,26962,24335],{"class":98},[92,26964,25121],{"class":98},[92,26966,26967],{"class":171}," \"héllo\"",[92,26969,26970],{"class":119}," { }            ",[92,26972,26973],{"class":134},"// byte index and rune of a string\n",[92,26975,26976,26978,26980,26982,26984,26987],{"class":94,"line":138},[92,26977,4906],{"class":98},[92,26979,26648],{"class":119},[92,26981,24335],{"class":98},[92,26983,25121],{"class":98},[92,26985,26986],{"class":119}," ch { }                    ",[92,26988,26989],{"class":134},"// values from a channel until it closes\n",[92,26991,26992,26994,26996,26998,27000,27002,27005],{"class":94,"line":143},[92,26993,4906],{"class":98},[92,26995,25242],{"class":119},[92,26997,24335],{"class":98},[92,26999,25121],{"class":98},[92,27001,1315],{"class":102},[92,27003,27004],{"class":119}," { }                     ",[92,27006,27007],{"class":134},"// 0,1,2,3,4 (Go 1.22+: range over an int)\n",[11,27009,27010,834,27012,27014],{},[15,27011,4614],{},[15,27013,4891],{}," accept a label so you can escape or skip an outer loop from inside a nested one, which is invaluable for grid and matrix problems:",[83,27016,27018],{"className":24256,"code":27017,"language":24258,"meta":88,"style":88},"outer:\nfor _, row := range grid {\n    for _, cell := range row {\n        if cell == target {\n            break outer            // exit both loops at once\n        }\n    }\n}\n",[15,27019,27020,27025,27038,27052,27064,27074,27078,27082],{"__ignoreMap":88},[92,27021,27022],{"class":94,"line":95},[92,27023,27024],{"class":119},"outer:\n",[92,27026,27027,27029,27032,27034,27036],{"class":94,"line":106},[92,27028,4906],{"class":98},[92,27030,27031],{"class":119}," _, row ",[92,27033,24335],{"class":98},[92,27035,25121],{"class":98},[92,27037,26093],{"class":119},[92,27039,27040,27042,27045,27047,27049],{"class":94,"line":113},[92,27041,5963],{"class":98},[92,27043,27044],{"class":119}," _, cell ",[92,27046,24335],{"class":98},[92,27048,25121],{"class":98},[92,27050,27051],{"class":119}," row {\n",[92,27053,27054,27056,27059,27061],{"class":94,"line":138},[92,27055,5044],{"class":98},[92,27057,27058],{"class":119}," cell ",[92,27060,1344],{"class":98},[92,27062,27063],{"class":119}," target {\n",[92,27065,27066,27068,27071],{"class":94,"line":143},[92,27067,5088],{"class":98},[92,27069,27070],{"class":119}," outer            ",[92,27072,27073],{"class":134},"// exit both loops at once\n",[92,27075,27076],{"class":94,"line":149},[92,27077,5070],{"class":119},[92,27079,27080],{"class":94,"line":155},[92,27081,5104],{"class":119},[92,27083,27084],{"class":94,"line":161},[92,27085,4711],{"class":119},[39,27087,5125],{"id":5124},[242,27089,27091],{"id":27090},"multiple-return-values-and-named-returns","Multiple return values and named returns",[11,27093,27094,27095,27098,27099,27102],{},"Functions are first-class values, and the defining Go feature is that they return ",[1511,27096,27097],{},"multiple"," values, which is how the language reports errors without exceptions. You can name the return values, which documents them and lets you use a bare ",[15,27100,27101],{},"return",", though heavy use of named returns tends to hurt readability.",[83,27104,27106],{"className":24256,"code":27105,"language":24258,"meta":88,"style":88},"func divmod(a, b int) (int, int) {   // two return values\n    return a / b, a % b\n}\nq, r := divmod(17, 5)                // 3, 2\n\nfunc split(sum int) (x, y int) {     // named returns\n    x = sum * 4 / 9\n    y = sum - x\n    return                           // bare return uses the named values\n}\n",[15,27107,27108,27142,27158,27162,27184,27188,27219,27237,27251,27258],{"__ignoreMap":88},[92,27109,27110,27112,27115,27117,27120,27122,27125,27127,27130,27132,27134,27136,27139],{"class":94,"line":95},[92,27111,24321],{"class":98},[92,27113,27114],{"class":5161}," divmod",[92,27116,120],{"class":119},[92,27118,23],{"class":27119},"s9osk",[92,27121,195],{"class":119},[92,27123,27124],{"class":27119},"b",[92,27126,5370],{"class":98},[92,27128,27129],{"class":119},") (",[92,27131,370],{"class":98},[92,27133,195],{"class":119},[92,27135,370],{"class":98},[92,27137,27138],{"class":119},") {   ",[92,27140,27141],{"class":134},"// two return values\n",[92,27143,27144,27146,27148,27150,27153,27155],{"class":94,"line":106},[92,27145,5195],{"class":98},[92,27147,15216],{"class":119},[92,27149,529],{"class":98},[92,27151,27152],{"class":119}," b, a ",[92,27154,1178],{"class":98},[92,27156,27157],{"class":119}," b\n",[92,27159,27160],{"class":94,"line":113},[92,27161,4711],{"class":119},[92,27163,27164,27167,27169,27171,27173,27175,27177,27179,27181],{"class":94,"line":138},[92,27165,27166],{"class":119},"q, r ",[92,27168,24335],{"class":98},[92,27170,27114],{"class":5161},[92,27172,120],{"class":119},[92,27174,9551],{"class":102},[92,27176,195],{"class":119},[92,27178,1463],{"class":102},[92,27180,25476],{"class":119},[92,27182,27183],{"class":134},"// 3, 2\n",[92,27185,27186],{"class":94,"line":143},[92,27187,110],{"emptyLinePlaceholder":109},[92,27189,27190,27192,27195,27197,27199,27201,27203,27206,27208,27211,27213,27216],{"class":94,"line":149},[92,27191,24321],{"class":98},[92,27193,27194],{"class":5161}," split",[92,27196,120],{"class":119},[92,27198,5394],{"class":27119},[92,27200,5370],{"class":98},[92,27202,27129],{"class":119},[92,27204,27205],{"class":27119},"x",[92,27207,195],{"class":119},[92,27209,27210],{"class":27119},"y",[92,27212,5370],{"class":98},[92,27214,27215],{"class":119},") {     ",[92,27217,27218],{"class":134},"// named returns\n",[92,27220,27221,27224,27226,27229,27231,27233,27235],{"class":94,"line":155},[92,27222,27223],{"class":119},"    x ",[92,27225,126],{"class":98},[92,27227,27228],{"class":119}," sum ",[92,27230,1959],{"class":98},[92,27232,1926],{"class":102},[92,27234,1222],{"class":98},[92,27236,26134],{"class":102},[92,27238,27239,27242,27244,27246,27248],{"class":94,"line":161},[92,27240,27241],{"class":119},"    y ",[92,27243,126],{"class":98},[92,27245,27228],{"class":119},[92,27247,1966],{"class":98},[92,27249,27250],{"class":119}," x\n",[92,27252,27253,27255],{"class":94,"line":166},[92,27254,5195],{"class":98},[92,27256,27257],{"class":134},"                           // bare return uses the named values\n",[92,27259,27260],{"class":94,"line":187},[92,27261,4711],{"class":119},[242,27263,27265],{"id":27264},"variadic-functions-and-closures","Variadic functions and closures",[11,27267,27268,27269,27272,27273,27275],{},"A variadic parameter, written ",[15,27270,27271],{},"...T",", accepts any number of trailing arguments as a slice, and you spread an existing slice into it with ",[15,27274,5335],{},". A closure is a function literal that captures variables from its surrounding scope by reference, which is how you carry state into callbacks.",[83,27277,27279],{"className":24256,"code":27278,"language":24258,"meta":88,"style":88},"func sum(nums ...int) int {          // nums is a []int inside the function\n    total := 0\n    for _, n := range nums {\n        total += n\n    }\n    return total\n}\nsum(1, 2, 3)                         // 6\nsum(existing...)                     // spread a slice\n\nfunc counter() func() int {          // returns a closure\n    count := 0\n    return func() int {\n        count++                      // captures and mutates count\n        return count\n    }\n}\nnext := counter()\nnext(); next()                       // 1, then 2\n",[15,27280,27281,27304,27314,27328,27338,27342,27349,27353,27374,27388,27392,27412,27421,27434,27444,27451,27455,27459,27471],{"__ignoreMap":88},[92,27282,27283,27285,27287,27289,27292,27295,27297,27299,27301],{"class":94,"line":95},[92,27284,24321],{"class":98},[92,27286,5355],{"class":5161},[92,27288,120],{"class":119},[92,27290,27291],{"class":27119},"nums",[92,27293,27294],{"class":98}," ...int",[92,27296,683],{"class":119},[92,27298,370],{"class":98},[92,27300,7117],{"class":119},[92,27302,27303],{"class":134},"// nums is a []int inside the function\n",[92,27305,27306,27309,27311],{"class":94,"line":106},[92,27307,27308],{"class":119},"    total ",[92,27310,24335],{"class":98},[92,27312,27313],{"class":102}," 0\n",[92,27315,27316,27318,27321,27323,27325],{"class":94,"line":113},[92,27317,5963],{"class":98},[92,27319,27320],{"class":119}," _, n ",[92,27322,24335],{"class":98},[92,27324,25121],{"class":98},[92,27326,27327],{"class":119}," nums {\n",[92,27329,27330,27333,27335],{"class":94,"line":138},[92,27331,27332],{"class":119},"        total ",[92,27334,1182],{"class":98},[92,27336,27337],{"class":119}," n\n",[92,27339,27340],{"class":94,"line":143},[92,27341,5104],{"class":119},[92,27343,27344,27346],{"class":94,"line":149},[92,27345,5195],{"class":98},[92,27347,27348],{"class":119}," total\n",[92,27350,27351],{"class":94,"line":155},[92,27352,4711],{"class":119},[92,27354,27355,27357,27359,27361,27363,27365,27367,27369,27372],{"class":94,"line":161},[92,27356,5394],{"class":5161},[92,27358,120],{"class":119},[92,27360,68],{"class":102},[92,27362,195],{"class":119},[92,27364,354],{"class":102},[92,27366,195],{"class":119},[92,27368,1448],{"class":102},[92,27370,27371],{"class":119},")                         ",[92,27373,5411],{"class":134},[92,27375,27376,27378,27381,27383,27385],{"class":94,"line":166},[92,27377,5394],{"class":5161},[92,27379,27380],{"class":119},"(existing",[92,27382,5335],{"class":98},[92,27384,25573],{"class":119},[92,27386,27387],{"class":134},"// spread a slice\n",[92,27389,27390],{"class":94,"line":187},[92,27391,110],{"emptyLinePlaceholder":109},[92,27393,27394,27396,27399,27401,27403,27405,27407,27409],{"class":94,"line":217},[92,27395,24321],{"class":98},[92,27397,27398],{"class":5161}," counter",[92,27400,7133],{"class":119},[92,27402,24321],{"class":98},[92,27404,7133],{"class":119},[92,27406,370],{"class":98},[92,27408,7117],{"class":119},[92,27410,27411],{"class":134},"// returns a closure\n",[92,27413,27414,27417,27419],{"class":94,"line":712},[92,27415,27416],{"class":119},"    count ",[92,27418,24335],{"class":98},[92,27420,27313],{"class":102},[92,27422,27423,27425,27428,27430,27432],{"class":94,"line":730},[92,27424,5195],{"class":98},[92,27426,27427],{"class":98}," func",[92,27429,7133],{"class":119},[92,27431,370],{"class":98},[92,27433,4695],{"class":119},[92,27435,27436,27439,27441],{"class":94,"line":747},[92,27437,27438],{"class":119},"        count",[92,27440,4926],{"class":98},[92,27442,27443],{"class":134},"                      // captures and mutates count\n",[92,27445,27446,27448],{"class":94,"line":763},[92,27447,6236],{"class":98},[92,27449,27450],{"class":119}," count\n",[92,27452,27453],{"class":94,"line":780},[92,27454,5104],{"class":119},[92,27456,27457],{"class":94,"line":785},[92,27458,4711],{"class":119},[92,27460,27461,27464,27466,27468],{"class":94,"line":2585},[92,27462,27463],{"class":119},"next ",[92,27465,24335],{"class":98},[92,27467,27398],{"class":5161},[92,27469,27470],{"class":119},"()\n",[92,27472,27473,27475,27478,27480,27483],{"class":94,"line":2605},[92,27474,6942],{"class":5161},[92,27476,27477],{"class":119},"(); ",[92,27479,6942],{"class":5161},[92,27481,27482],{"class":119},"()                       ",[92,27484,27485],{"class":134},"// 1, then 2\n",[242,27487,27489],{"id":27488},"defer-panic-and-recover","defer, panic, and recover",[11,27491,27492,27495,27496,27501],{},[15,27493,27494],{},"defer"," schedules a function call to run when the surrounding function returns, no matter how it returns, which is the clean way to release resources such as files, locks, and connections. Deferred calls run in last-in-first-out order, and their arguments are evaluated ",[1511,27497,27498,27499],{},"at the point of ",[15,27500,27494],{},", not when they actually run, which is a common surprise.",[83,27503,27505],{"className":24256,"code":27504,"language":24258,"meta":88,"style":88},"func readFile(path string) error {\n    f, err := os.Open(path)\n    if err != nil {\n        return err\n    }\n    defer f.Close()                  // runs when readFile returns, however it returns\n\n    i := 0\n    defer fmt.Println(\"deferred i =\", i) // prints 0: i was captured at defer time\n    i = 99\n    return nil\n}\n",[15,27506,27507,27528,27544,27558,27565,27569,27586,27590,27599,27619,27628,27635],{"__ignoreMap":88},[92,27508,27509,27511,27514,27516,27519,27521,27523,27526],{"class":94,"line":95},[92,27510,24321],{"class":98},[92,27512,27513],{"class":5161}," readFile",[92,27515,120],{"class":119},[92,27517,27518],{"class":27119},"path",[92,27520,5188],{"class":98},[92,27522,683],{"class":119},[92,27524,27525],{"class":98},"error",[92,27527,4695],{"class":119},[92,27529,27530,27533,27535,27538,27541],{"class":94,"line":106},[92,27531,27532],{"class":119},"    f, err ",[92,27534,24335],{"class":98},[92,27536,27537],{"class":119}," os.",[92,27539,27540],{"class":5161},"Open",[92,27542,27543],{"class":119},"(path)\n",[92,27545,27546,27548,27551,27553,27556],{"class":94,"line":113},[92,27547,9161],{"class":98},[92,27549,27550],{"class":119}," err ",[92,27552,1356],{"class":98},[92,27554,27555],{"class":102}," nil",[92,27557,4695],{"class":119},[92,27559,27560,27562],{"class":94,"line":138},[92,27561,6236],{"class":98},[92,27563,27564],{"class":119}," err\n",[92,27566,27567],{"class":94,"line":143},[92,27568,5104],{"class":119},[92,27570,27571,27574,27577,27580,27583],{"class":94,"line":149},[92,27572,27573],{"class":98},"    defer",[92,27575,27576],{"class":119}," f.",[92,27578,27579],{"class":5161},"Close",[92,27581,27582],{"class":119},"()                  ",[92,27584,27585],{"class":134},"// runs when readFile returns, however it returns\n",[92,27587,27588],{"class":94,"line":155},[92,27589,110],{"emptyLinePlaceholder":109},[92,27591,27592,27595,27597],{"class":94,"line":161},[92,27593,27594],{"class":119},"    i ",[92,27596,24335],{"class":98},[92,27598,27313],{"class":102},[92,27600,27601,27603,27606,27608,27610,27613,27616],{"class":94,"line":166},[92,27602,27573],{"class":98},[92,27604,27605],{"class":119}," fmt.",[92,27607,24356],{"class":5161},[92,27609,120],{"class":119},[92,27611,27612],{"class":171},"\"deferred i =\"",[92,27614,27615],{"class":119},", i) ",[92,27617,27618],{"class":134},"// prints 0: i was captured at defer time\n",[92,27620,27621,27623,27625],{"class":94,"line":187},[92,27622,27594],{"class":119},[92,27624,126],{"class":98},[92,27626,27627],{"class":102}," 99\n",[92,27629,27630,27632],{"class":94,"line":217},[92,27631,5195],{"class":98},[92,27633,27634],{"class":102}," nil\n",[92,27636,27637],{"class":94,"line":712},[92,27638,4711],{"class":119},[11,27640,27641,27644,27645,27648],{},[15,27642,27643],{},"panic"," stops normal flow and unwinds the stack running deferred calls, and ",[15,27646,27647],{},"recover",", called inside a deferred function, stops that unwinding and returns the panic value. This pair is Go's last-resort mechanism for truly exceptional situations, not its everyday error handling.",[83,27650,27652],{"className":24256,"code":27651,"language":24258,"meta":88,"style":88},"func safeDivide(a, b int) (result int, err error) {\n    defer func() {\n        if r := recover(); r != nil {       // catch the panic\n            err = fmt.Errorf(\"recovered: %v\", r)\n        }\n    }()\n    return a / b, nil                       // a divide-by-zero panics; recover turns it into err\n}\n",[15,27653,27654,27688,27696,27720,27745,27749,27754,27770],{"__ignoreMap":88},[92,27655,27656,27658,27661,27663,27665,27667,27669,27671,27673,27676,27678,27680,27683,27686],{"class":94,"line":95},[92,27657,24321],{"class":98},[92,27659,27660],{"class":5161}," safeDivide",[92,27662,120],{"class":119},[92,27664,23],{"class":27119},[92,27666,195],{"class":119},[92,27668,27124],{"class":27119},[92,27670,5370],{"class":98},[92,27672,27129],{"class":119},[92,27674,27675],{"class":27119},"result",[92,27677,5370],{"class":98},[92,27679,195],{"class":119},[92,27681,27682],{"class":27119},"err",[92,27684,27685],{"class":98}," error",[92,27687,4647],{"class":119},[92,27689,27690,27692,27694],{"class":94,"line":106},[92,27691,27573],{"class":98},[92,27693,27427],{"class":98},[92,27695,24327],{"class":119},[92,27697,27698,27700,27703,27705,27708,27711,27713,27715,27717],{"class":94,"line":113},[92,27699,5044],{"class":98},[92,27701,27702],{"class":119}," r ",[92,27704,24335],{"class":98},[92,27706,27707],{"class":5161}," recover",[92,27709,27710],{"class":119},"(); r ",[92,27712,1356],{"class":98},[92,27714,27555],{"class":102},[92,27716,7254],{"class":119},[92,27718,27719],{"class":134},"// catch the panic\n",[92,27721,27722,27725,27727,27729,27732,27734,27737,27740,27742],{"class":94,"line":138},[92,27723,27724],{"class":119},"            err ",[92,27726,126],{"class":98},[92,27728,27605],{"class":119},[92,27730,27731],{"class":5161},"Errorf",[92,27733,120],{"class":119},[92,27735,27736],{"class":171},"\"recovered: ",[92,27738,27739],{"class":102},"%v",[92,27741,178],{"class":171},[92,27743,27744],{"class":119},", r)\n",[92,27746,27747],{"class":94,"line":143},[92,27748,5070],{"class":119},[92,27750,27751],{"class":94,"line":149},[92,27752,27753],{"class":119},"    }()\n",[92,27755,27756,27758,27760,27762,27765,27767],{"class":94,"line":155},[92,27757,5195],{"class":98},[92,27759,15216],{"class":119},[92,27761,529],{"class":98},[92,27763,27764],{"class":119}," b, ",[92,27766,24556],{"class":102},[92,27768,27769],{"class":134},"                       // a divide-by-zero panics; recover turns it into err\n",[92,27771,27772],{"class":94,"line":161},[92,27773,4711],{"class":119},[39,27775,27777],{"id":27776},"structs-methods-and-interfaces","Structs, Methods, and Interfaces",[11,27779,27780],{},"Go has no classes and no inheritance. Instead it composes behavior from structs, methods, and interfaces, which together cover what other languages do with objects but with different rules.",[242,27782,27784],{"id":27783},"structs","Structs",[11,27786,27787,27788,27791,27792,27794,27795,27798],{},"A struct groups named fields into a single type. You create one with a literal (positional or, better, by field name), and Go structs are ",[1511,27789,27790],{},"value types",", so assigning one copies every field. Two structs of the same type are comparable with ",[15,27793,1344],{}," when all their fields are comparable. Struct tags, the backtick strings after a field, attach metadata that packages like ",[15,27796,27797],{},"encoding/json"," read at runtime.",[83,27800,27802],{"className":24256,"code":27801,"language":24258,"meta":88,"style":88},"type User struct {\n    ID    int\n    Name  string    `json:\"name\"`     // struct tag: JSON key becomes \"name\"\n    Email string    `json:\"email,omitempty\"`\n}\n\nu := User{ID: 1, Name: \"Ada\"}         // named fields (preferred)\nu2 := User{2, \"Lin\", \"lin@x.io\"}      // positional (fragile; avoid)\np := &User{Name: \"Joy\"}               // &T{} makes a pointer to a new struct\n\nu.Name                                // field access with . on value or pointer\np.Name                                // Go auto-dereferences: no (*p).Name needed\n",[15,27803,27804,27814,27821,27834,27844,27848,27852,27877,27906,27930,27934,27942],{"__ignoreMap":88},[92,27805,27806,27808,27810,27812],{"class":94,"line":95},[92,27807,24766],{"class":98},[92,27809,8699],{"class":5161},[92,27811,26399],{"class":98},[92,27813,4695],{"class":119},[92,27815,27816,27819],{"class":94,"line":106},[92,27817,27818],{"class":119},"    ID    ",[92,27820,26018],{"class":98},[92,27822,27823,27826,27828,27831],{"class":94,"line":113},[92,27824,27825],{"class":119},"    Name  ",[92,27827,376],{"class":98},[92,27829,27830],{"class":171},"    `json:\"name\"`",[92,27832,27833],{"class":134},"     // struct tag: JSON key becomes \"name\"\n",[92,27835,27836,27839,27841],{"class":94,"line":138},[92,27837,27838],{"class":119},"    Email ",[92,27840,376],{"class":98},[92,27842,27843],{"class":171},"    `json:\"email,omitempty\"`\n",[92,27845,27846],{"class":94,"line":143},[92,27847,4711],{"class":119},[92,27849,27850],{"class":94,"line":149},[92,27851,110],{"emptyLinePlaceholder":109},[92,27853,27854,27856,27858,27860,27863,27865,27868,27871,27874],{"class":94,"line":155},[92,27855,24684],{"class":119},[92,27857,24335],{"class":98},[92,27859,8699],{"class":5161},[92,27861,27862],{"class":119},"{ID: ",[92,27864,68],{"class":102},[92,27866,27867],{"class":119},", Name: ",[92,27869,27870],{"class":171},"\"Ada\"",[92,27872,27873],{"class":119},"}         ",[92,27875,27876],{"class":134},"// named fields (preferred)\n",[92,27878,27879,27882,27884,27886,27888,27890,27892,27895,27897,27900,27903],{"class":94,"line":161},[92,27880,27881],{"class":119},"u2 ",[92,27883,24335],{"class":98},[92,27885,8699],{"class":5161},[92,27887,25418],{"class":119},[92,27889,354],{"class":102},[92,27891,195],{"class":119},[92,27893,27894],{"class":171},"\"Lin\"",[92,27896,195],{"class":119},[92,27898,27899],{"class":171},"\"lin@x.io\"",[92,27901,27902],{"class":119},"}      ",[92,27904,27905],{"class":134},"// positional (fragile; avoid)\n",[92,27907,27908,27911,27913,27915,27918,27921,27924,27927],{"class":94,"line":166},[92,27909,27910],{"class":119},"p ",[92,27912,24335],{"class":98},[92,27914,1895],{"class":98},[92,27916,27917],{"class":5161},"User",[92,27919,27920],{"class":119},"{Name: ",[92,27922,27923],{"class":171},"\"Joy\"",[92,27925,27926],{"class":119},"}               ",[92,27928,27929],{"class":134},"// &T{} makes a pointer to a new struct\n",[92,27931,27932],{"class":94,"line":187},[92,27933,110],{"emptyLinePlaceholder":109},[92,27935,27936,27939],{"class":94,"line":217},[92,27937,27938],{"class":119},"u.Name                                ",[92,27940,27941],{"class":134},"// field access with . on value or pointer\n",[92,27943,27944,27947],{"class":94,"line":712},[92,27945,27946],{"class":119},"p.Name                                ",[92,27948,27949],{"class":134},"// Go auto-dereferences: no (*p).Name needed\n",[242,27951,27953],{"id":27952},"methods-and-receivers","Methods and receivers",[11,27955,27956,27957,27960],{},"A method is a function with a ",[1511,27958,27959],{},"receiver"," argument written before the name, which binds it to a type. The receiver can be a value (the method gets a copy) or a pointer (the method can mutate the original). Choosing between them follows clear rules:",[11016,27962,27963,27970,27976],{},[11019,27964,27965,27966,27969],{},"Use a ",[10490,27967,27968],{},"pointer receiver"," when the method modifies the receiver, or when the struct is large and you want to avoid copying it.",[11019,27971,27965,27972,27975],{},[10490,27973,27974],{},"value receiver"," for small, immutable types where a copy is cheap and mutation is not wanted.",[11019,27977,27978],{},"Be consistent: if any method needs a pointer receiver, give all methods on that type pointer receivers, so the method set stays uniform.",[83,27980,27982],{"className":24256,"code":27981,"language":24258,"meta":88,"style":88},"type Counter struct{ n int }\n\nfunc (c Counter) Value() int { return c.n }  // value receiver: reads a copy\nfunc (c *Counter) Inc()      { c.n++ }        // pointer receiver: mutates the original\n\nc := Counter{}\nc.Inc()           // Go takes the address automatically for you\nc.Value()         // 1\n",[15,27983,27984,27999,28003,28034,28062,28066,28077,28090],{"__ignoreMap":88},[92,27985,27986,27988,27990,27992,27995,27997],{"class":94,"line":95},[92,27987,24766],{"class":98},[92,27989,6842],{"class":5161},[92,27991,26399],{"class":98},[92,27993,27994],{"class":119},"{ n ",[92,27996,370],{"class":98},[92,27998,4506],{"class":119},[92,28000,28001],{"class":94,"line":106},[92,28002,110],{"emptyLinePlaceholder":109},[92,28004,28005,28007,28009,28012,28014,28016,28019,28021,28023,28026,28028,28031],{"class":94,"line":113},[92,28006,24321],{"class":98},[92,28008,3559],{"class":119},[92,28010,28011],{"class":27119},"c ",[92,28013,6937],{"class":5161},[92,28015,683],{"class":119},[92,28017,28018],{"class":5161},"Value",[92,28020,7133],{"class":119},[92,28022,370],{"class":98},[92,28024,28025],{"class":119}," { ",[92,28027,27101],{"class":98},[92,28029,28030],{"class":119}," c.n }  ",[92,28032,28033],{"class":134},"// value receiver: reads a copy\n",[92,28035,28036,28038,28040,28042,28044,28046,28048,28051,28054,28056,28059],{"class":94,"line":138},[92,28037,24321],{"class":98},[92,28039,3559],{"class":119},[92,28041,28011],{"class":27119},[92,28043,1959],{"class":98},[92,28045,6937],{"class":5161},[92,28047,683],{"class":119},[92,28049,28050],{"class":5161},"Inc",[92,28052,28053],{"class":119},"()      { c.n",[92,28055,4926],{"class":98},[92,28057,28058],{"class":119}," }        ",[92,28060,28061],{"class":134},"// pointer receiver: mutates the original\n",[92,28063,28064],{"class":94,"line":143},[92,28065,110],{"emptyLinePlaceholder":109},[92,28067,28068,28070,28072,28074],{"class":94,"line":149},[92,28069,28011],{"class":119},[92,28071,24335],{"class":98},[92,28073,6842],{"class":5161},[92,28075,28076],{"class":119},"{}\n",[92,28078,28079,28082,28084,28087],{"class":94,"line":155},[92,28080,28081],{"class":119},"c.",[92,28083,28050],{"class":5161},[92,28085,28086],{"class":119},"()           ",[92,28088,28089],{"class":134},"// Go takes the address automatically for you\n",[92,28091,28092,28094,28096,28099],{"class":94,"line":161},[92,28093,28081],{"class":119},[92,28095,28018],{"class":5161},[92,28097,28098],{"class":119},"()         ",[92,28100,6948],{"class":134},[242,28102,28104],{"id":28103},"embedding-for-composition","Embedding for composition",[11,28106,28107,28108,28111],{},"Go replaces inheritance with ",[1511,28109,28110],{},"embedding",": put one type inside another without a field name, and its fields and methods are promoted to the outer type. The outer type does not become a subtype, but it gains the embedded behavior, which is composition made syntactically convenient.",[83,28113,28115],{"className":24256,"code":28114,"language":24258,"meta":88,"style":88},"type Animal struct{ Name string }\nfunc (a Animal) Speak() string { return a.Name + \" makes a sound\" }\n\ntype Dog struct {\n    Animal          // embedded (no field name)\n    Breed string\n}\n\nd := Dog{Animal: Animal{Name: \"Rex\"}, Breed: \"Lab\"}\nd.Name            // \"Rex\": promoted from Animal\nd.Speak()         // \"Rex makes a sound\": promoted method\n",[15,28116,28117,28132,28167,28171,28181,28189,28197,28201,28205,28232,28240],{"__ignoreMap":88},[92,28118,28119,28121,28123,28125,28128,28130],{"class":94,"line":95},[92,28120,24766],{"class":98},[92,28122,7021],{"class":5161},[92,28124,26399],{"class":98},[92,28126,28127],{"class":119},"{ Name ",[92,28129,376],{"class":98},[92,28131,4506],{"class":119},[92,28133,28134,28136,28138,28141,28144,28146,28149,28151,28153,28155,28157,28160,28162,28165],{"class":94,"line":106},[92,28135,24321],{"class":98},[92,28137,3559],{"class":119},[92,28139,28140],{"class":27119},"a ",[92,28142,28143],{"class":5161},"Animal",[92,28145,683],{"class":119},[92,28147,28148],{"class":5161},"Speak",[92,28150,7133],{"class":119},[92,28152,376],{"class":98},[92,28154,28025],{"class":119},[92,28156,27101],{"class":98},[92,28158,28159],{"class":119}," a.Name ",[92,28161,1795],{"class":98},[92,28163,28164],{"class":171}," \" makes a sound\"",[92,28166,4506],{"class":119},[92,28168,28169],{"class":94,"line":113},[92,28170,110],{"emptyLinePlaceholder":109},[92,28172,28173,28175,28177,28179],{"class":94,"line":138},[92,28174,24766],{"class":98},[92,28176,7093],{"class":5161},[92,28178,26399],{"class":98},[92,28180,4695],{"class":119},[92,28182,28183,28186],{"class":94,"line":143},[92,28184,28185],{"class":5161},"    Animal",[92,28187,28188],{"class":134},"          // embedded (no field name)\n",[92,28190,28191,28194],{"class":94,"line":149},[92,28192,28193],{"class":119},"    Breed ",[92,28195,28196],{"class":98},"string\n",[92,28198,28199],{"class":94,"line":155},[92,28200,4711],{"class":119},[92,28202,28203],{"class":94,"line":161},[92,28204,110],{"emptyLinePlaceholder":109},[92,28206,28207,28210,28212,28214,28217,28219,28221,28224,28227,28230],{"class":94,"line":166},[92,28208,28209],{"class":119},"d ",[92,28211,24335],{"class":98},[92,28213,7093],{"class":5161},[92,28215,28216],{"class":119},"{Animal: ",[92,28218,28143],{"class":5161},[92,28220,27920],{"class":119},[92,28222,28223],{"class":171},"\"Rex\"",[92,28225,28226],{"class":119},"}, Breed: ",[92,28228,28229],{"class":171},"\"Lab\"",[92,28231,4711],{"class":119},[92,28233,28234,28237],{"class":94,"line":187},[92,28235,28236],{"class":119},"d.Name            ",[92,28238,28239],{"class":134},"// \"Rex\": promoted from Animal\n",[92,28241,28242,28245,28247,28249],{"class":94,"line":217},[92,28243,28244],{"class":119},"d.",[92,28246,28148],{"class":5161},[92,28248,28098],{"class":119},[92,28250,28251],{"class":134},"// \"Rex makes a sound\": promoted method\n",[242,28253,7413],{"id":7412},[11,28255,28256,28257,28260,28261,28263,28264,28267],{},"An interface is a set of method signatures, and a type satisfies it ",[1511,28258,28259],{},"implicitly"," simply by having those methods; there is no ",[15,28262,7419],{}," keyword and no declared relationship. This is the single biggest design difference from Java or C#, and it is why Go interfaces are usually tiny (often one method) and defined by the code that ",[1511,28265,28266],{},"consumes"," them, not the code that provides them.",[83,28269,28271],{"className":24256,"code":28270,"language":24258,"meta":88,"style":88},"type Shape interface {\n    Area() float64                   // any type with this method satisfies Shape\n}\n\ntype Circle struct{ R float64 }\nfunc (c Circle) Area() float64 { return math.Pi * c.R * c.R }\n\n// Circle satisfies Shape automatically; no declaration is needed.\nvar s Shape = Circle{R: 2}\ns.Area()                             // 12.566...\n",[15,28272,28273,28284,28296,28300,28304,28319,28356,28360,28365,28386],{"__ignoreMap":88},[92,28274,28275,28277,28279,28282],{"class":94,"line":95},[92,28276,24766],{"class":98},[92,28278,7207],{"class":5161},[92,28280,28281],{"class":98}," interface",[92,28283,4695],{"class":119},[92,28285,28286,28289,28291,28293],{"class":94,"line":106},[92,28287,28288],{"class":5161},"    Area",[92,28290,7133],{"class":119},[92,28292,24534],{"class":98},[92,28294,28295],{"class":134},"                   // any type with this method satisfies Shape\n",[92,28297,28298],{"class":94,"line":113},[92,28299,4711],{"class":119},[92,28301,28302],{"class":94,"line":138},[92,28303,110],{"emptyLinePlaceholder":109},[92,28305,28306,28308,28310,28312,28315,28317],{"class":94,"line":143},[92,28307,24766],{"class":98},[92,28309,7303],{"class":5161},[92,28311,26399],{"class":98},[92,28313,28314],{"class":119},"{ R ",[92,28316,24534],{"class":98},[92,28318,4506],{"class":119},[92,28320,28321,28323,28325,28327,28330,28332,28335,28337,28339,28341,28343,28346,28348,28351,28353],{"class":94,"line":149},[92,28322,24321],{"class":98},[92,28324,3559],{"class":119},[92,28326,28011],{"class":27119},[92,28328,28329],{"class":5161},"Circle",[92,28331,683],{"class":119},[92,28333,28334],{"class":5161},"Area",[92,28336,7133],{"class":119},[92,28338,24534],{"class":98},[92,28340,28025],{"class":119},[92,28342,27101],{"class":98},[92,28344,28345],{"class":119}," math.Pi ",[92,28347,1959],{"class":98},[92,28349,28350],{"class":119}," c.R ",[92,28352,1959],{"class":98},[92,28354,28355],{"class":119}," c.R }\n",[92,28357,28358],{"class":94,"line":155},[92,28359,110],{"emptyLinePlaceholder":109},[92,28361,28362],{"class":94,"line":161},[92,28363,28364],{"class":134},"// Circle satisfies Shape automatically; no declaration is needed.\n",[92,28366,28367,28369,28372,28375,28377,28379,28382,28384],{"class":94,"line":166},[92,28368,24414],{"class":98},[92,28370,28371],{"class":119}," s ",[92,28373,28374],{"class":5161},"Shape",[92,28376,853],{"class":98},[92,28378,7303],{"class":5161},[92,28380,28381],{"class":119},"{R: ",[92,28383,354],{"class":102},[92,28385,4711],{"class":119},[92,28387,28388,28391,28393,28396],{"class":94,"line":187},[92,28389,28390],{"class":119},"s.",[92,28392,28334],{"class":5161},[92,28394,28395],{"class":119},"()                             ",[92,28397,28398],{"class":134},"// 12.566...\n",[11,28400,28401,28402,28405,28406,28409,28410,81],{},"The empty interface, spelled ",[15,28403,28404],{},"any"," since Go 1.18, holds a value of any type. You get the concrete value back out with a ",[1511,28407,28408],{},"type assertion"," (in comma-ok form so a wrong guess does not panic) or a ",[1511,28411,26635],{},[83,28413,28415],{"className":24256,"code":28414,"language":24258,"meta":88,"style":88},"var x any = \"hello\"\n\nstr, ok := x.(string)   // type assertion, comma-ok form: str=\"hello\", ok=true\nn, ok := x.(int)        // ok=false, n=0 (no panic because of the comma-ok form)\n\nswitch v := x.(type) {  // type switch: branch on the dynamic type\ncase string:\n    fmt.Println(\"string of length\", len(v))\ncase int:\n    fmt.Println(\"int\", v)\ndefault:\n    fmt.Println(\"something else\")\n}\n",[15,28416,28417,28431,28435,28452,28468,28472,28490,28498,28516,28524,28538,28544,28557],{"__ignoreMap":88},[92,28418,28419,28421,28424,28426,28428],{"class":94,"line":95},[92,28420,24414],{"class":98},[92,28422,28423],{"class":119}," x ",[92,28425,28404],{"class":5161},[92,28427,853],{"class":98},[92,28429,28430],{"class":171}," \"hello\"\n",[92,28432,28433],{"class":94,"line":106},[92,28434,110],{"emptyLinePlaceholder":109},[92,28436,28437,28440,28442,28445,28447,28449],{"class":94,"line":113},[92,28438,28439],{"class":119},"str, ok ",[92,28441,24335],{"class":98},[92,28443,28444],{"class":119}," x.(",[92,28446,376],{"class":98},[92,28448,25336],{"class":119},[92,28450,28451],{"class":134},"// type assertion, comma-ok form: str=\"hello\", ok=true\n",[92,28453,28454,28457,28459,28461,28463,28465],{"class":94,"line":138},[92,28455,28456],{"class":119},"n, ok ",[92,28458,24335],{"class":98},[92,28460,28444],{"class":119},[92,28462,370],{"class":98},[92,28464,25511],{"class":119},[92,28466,28467],{"class":134},"// ok=false, n=0 (no panic because of the comma-ok form)\n",[92,28469,28470],{"class":94,"line":143},[92,28471,110],{"emptyLinePlaceholder":109},[92,28473,28474,28476,28478,28480,28482,28484,28487],{"class":94,"line":149},[92,28475,4606],{"class":98},[92,28477,26648],{"class":119},[92,28479,24335],{"class":98},[92,28481,28444],{"class":119},[92,28483,24766],{"class":98},[92,28485,28486],{"class":119},") {  ",[92,28488,28489],{"class":134},"// type switch: branch on the dynamic type\n",[92,28491,28492,28494,28496],{"class":94,"line":155},[92,28493,26715],{"class":98},[92,28495,5188],{"class":98},[92,28497,4828],{"class":119},[92,28499,28500,28502,28504,28506,28509,28511,28513],{"class":94,"line":161},[92,28501,24353],{"class":119},[92,28503,24356],{"class":5161},[92,28505,120],{"class":119},[92,28507,28508],{"class":171},"\"string of length\"",[92,28510,195],{"class":119},[92,28512,25086],{"class":5161},[92,28514,28515],{"class":119},"(v))\n",[92,28517,28518,28520,28522],{"class":94,"line":166},[92,28519,26715],{"class":98},[92,28521,5370],{"class":98},[92,28523,4828],{"class":119},[92,28525,28526,28528,28530,28532,28535],{"class":94,"line":187},[92,28527,24353],{"class":119},[92,28529,24356],{"class":5161},[92,28531,120],{"class":119},[92,28533,28534],{"class":171},"\"int\"",[92,28536,28537],{"class":119},", v)\n",[92,28539,28540,28542],{"class":94,"line":217},[92,28541,4628],{"class":98},[92,28543,4828],{"class":119},[92,28545,28546,28548,28550,28552,28555],{"class":94,"line":712},[92,28547,24353],{"class":119},[92,28549,24356],{"class":5161},[92,28551,120],{"class":119},[92,28553,28554],{"class":171},"\"something else\"",[92,28556,24307],{"class":119},[92,28558,28559],{"class":94,"line":730},[92,28560,4711],{"class":119},[242,28562,28564],{"id":28563},"an-interface-value-is-a-type-value-pair","An interface value is a (type, value) pair",[11,28566,28567,28568,28570,28571,28574,28575,28577,28578,28581,28582,28584,28585,28587],{},"Internally, an interface value holds two words: the concrete ",[1511,28569,24766],{}," it currently stores and a ",[1511,28572,28573],{},"pointer to the value",". An interface is ",[15,28576,24556],{}," only when ",[1511,28579,28580],{},"both"," are nil. This is the mechanism behind the notorious typed-nil bug: if you store a nil pointer of a concrete type in an interface, the interface holds a non-nil type, so it compares as ",[1511,28583,5608],{}," equal to ",[15,28586,24556],{}," even though the underlying pointer is nil.",[11,28589,28590],{},[3108,28591],{"alt":28592,"src":28593},"A Go interface value shown as a type word and a value word, illustrating the typed-nil trap","/post-images/go-syntax-recap/go-interface-value.png",[39,28595,28597],{"id":28596},"error-handling","Error Handling",[242,28599,28601],{"id":28600},"errors-are-values","Errors are values",[11,28603,28604,28605,28607,28608,28610,28611,28614,28615,28618],{},"Go has no exceptions for ordinary failures. Instead a function that can fail returns an ",[15,28606,27525],{}," as its last value, and the caller checks it immediately; ",[15,28609,27525],{}," is just an interface with a single ",[15,28612,28613],{},"Error() string"," method. This makes the failure path explicit and local, at the cost of the repetitive ",[15,28616,28617],{},"if err != nil"," you will write constantly.",[83,28620,28622],{"className":24256,"code":28621,"language":24258,"meta":88,"style":88},"f, err := os.Open(\"config.yaml\")\nif err != nil {\n    return err              // handle or propagate; do not ignore\n}\ndefer f.Close()\n\n// Create simple errors with errors.New or fmt.Errorf:\nerr1 := errors.New(\"not found\")\nerr2 := fmt.Errorf(\"user %d: %w\", id, err1) // %w wraps err1 so it can be unwrapped\n",[15,28623,28624,28642,28654,28664,28668,28678,28682,28687,28707],{"__ignoreMap":88},[92,28625,28626,28629,28631,28633,28635,28637,28640],{"class":94,"line":95},[92,28627,28628],{"class":119},"f, err ",[92,28630,24335],{"class":98},[92,28632,27537],{"class":119},[92,28634,27540],{"class":5161},[92,28636,120],{"class":119},[92,28638,28639],{"class":171},"\"config.yaml\"",[92,28641,24307],{"class":119},[92,28643,28644,28646,28648,28650,28652],{"class":94,"line":106},[92,28645,4588],{"class":98},[92,28647,27550],{"class":119},[92,28649,1356],{"class":98},[92,28651,27555],{"class":102},[92,28653,4695],{"class":119},[92,28655,28656,28658,28661],{"class":94,"line":113},[92,28657,5195],{"class":98},[92,28659,28660],{"class":119}," err              ",[92,28662,28663],{"class":134},"// handle or propagate; do not ignore\n",[92,28665,28666],{"class":94,"line":138},[92,28667,4711],{"class":119},[92,28669,28670,28672,28674,28676],{"class":94,"line":143},[92,28671,27494],{"class":98},[92,28673,27576],{"class":119},[92,28675,27579],{"class":5161},[92,28677,27470],{"class":119},[92,28679,28680],{"class":94,"line":149},[92,28681,110],{"emptyLinePlaceholder":109},[92,28683,28684],{"class":94,"line":155},[92,28685,28686],{"class":134},"// Create simple errors with errors.New or fmt.Errorf:\n",[92,28688,28689,28692,28694,28697,28700,28702,28705],{"class":94,"line":161},[92,28690,28691],{"class":119},"err1 ",[92,28693,24335],{"class":98},[92,28695,28696],{"class":119}," errors.",[92,28698,28699],{"class":5161},"New",[92,28701,120],{"class":119},[92,28703,28704],{"class":171},"\"not found\"",[92,28706,24307],{"class":119},[92,28708,28709,28712,28714,28716,28718,28720,28723,28725,28727,28730,28732,28735],{"class":94,"line":166},[92,28710,28711],{"class":119},"err2 ",[92,28713,24335],{"class":98},[92,28715,27605],{"class":119},[92,28717,27731],{"class":5161},[92,28719,120],{"class":119},[92,28721,28722],{"class":171},"\"user ",[92,28724,25141],{"class":102},[92,28726,5263],{"class":171},[92,28728,28729],{"class":102},"%w",[92,28731,178],{"class":171},[92,28733,28734],{"class":119},", id, err1) ",[92,28736,28737],{"class":134},"// %w wraps err1 so it can be unwrapped\n",[242,28739,28741],{"id":28740},"wrapping-is-and-as","Wrapping, Is, and As",[11,28743,28744,28745,28747,28748,28751,28752,15200,28754,28757,28758,28760],{},"Wrapping an error with the ",[15,28746,28729],{}," verb preserves the original while adding context, building a chain you can inspect. You compare against a known sentinel error with ",[15,28749,28750],{},"errors.Is",", and you extract a specific error ",[1511,28753,24766],{},[15,28755,28756],{},"errors.As","; never compare wrapped errors with ",[15,28759,1344],{},", because the wrapper is a different value.",[83,28762,28764],{"className":24256,"code":28763,"language":24258,"meta":88,"style":88},"var ErrNotFound = errors.New(\"not found\")   // a sentinel error\n\nfunc lookup(id int) error {\n    return fmt.Errorf(\"lookup %d: %w\", id, ErrNotFound) // wrap the sentinel\n}\n\nerr := lookup(7)\nerrors.Is(err, ErrNotFound)   // true: unwraps the chain to find the sentinel\n\nvar pathErr *os.PathError\nif errors.As(err, &pathErr) { // true if some error in the chain is *os.PathError\n    fmt.Println(pathErr.Path)\n}\n",[15,28765,28766,28788,28792,28812,28839,28843,28847,28862,28876,28880,28897,28917,28926],{"__ignoreMap":88},[92,28767,28768,28770,28773,28775,28777,28779,28781,28783,28785],{"class":94,"line":95},[92,28769,24414],{"class":98},[92,28771,28772],{"class":119}," ErrNotFound ",[92,28774,126],{"class":98},[92,28776,28696],{"class":119},[92,28778,28699],{"class":5161},[92,28780,120],{"class":119},[92,28782,28704],{"class":171},[92,28784,25336],{"class":119},[92,28786,28787],{"class":134},"// a sentinel error\n",[92,28789,28790],{"class":94,"line":106},[92,28791,110],{"emptyLinePlaceholder":109},[92,28793,28794,28796,28799,28801,28804,28806,28808,28810],{"class":94,"line":113},[92,28795,24321],{"class":98},[92,28797,28798],{"class":5161}," lookup",[92,28800,120],{"class":119},[92,28802,28803],{"class":27119},"id",[92,28805,5370],{"class":98},[92,28807,683],{"class":119},[92,28809,27525],{"class":98},[92,28811,4695],{"class":119},[92,28813,28814,28816,28818,28820,28822,28825,28827,28829,28831,28833,28836],{"class":94,"line":138},[92,28815,5195],{"class":98},[92,28817,27605],{"class":119},[92,28819,27731],{"class":5161},[92,28821,120],{"class":119},[92,28823,28824],{"class":171},"\"lookup ",[92,28826,25141],{"class":102},[92,28828,5263],{"class":171},[92,28830,28729],{"class":102},[92,28832,178],{"class":171},[92,28834,28835],{"class":119},", id, ErrNotFound) ",[92,28837,28838],{"class":134},"// wrap the sentinel\n",[92,28840,28841],{"class":94,"line":143},[92,28842,4711],{"class":119},[92,28844,28845],{"class":94,"line":149},[92,28846,110],{"emptyLinePlaceholder":109},[92,28848,28849,28852,28854,28856,28858,28860],{"class":94,"line":155},[92,28850,28851],{"class":119},"err ",[92,28853,24335],{"class":98},[92,28855,28798],{"class":5161},[92,28857,120],{"class":119},[92,28859,1205],{"class":102},[92,28861,24307],{"class":119},[92,28863,28864,28867,28870,28873],{"class":94,"line":161},[92,28865,28866],{"class":119},"errors.",[92,28868,28869],{"class":5161},"Is",[92,28871,28872],{"class":119},"(err, ErrNotFound)   ",[92,28874,28875],{"class":134},"// true: unwraps the chain to find the sentinel\n",[92,28877,28878],{"class":94,"line":166},[92,28879,110],{"emptyLinePlaceholder":109},[92,28881,28882,28884,28887,28889,28892,28894],{"class":94,"line":187},[92,28883,24414],{"class":98},[92,28885,28886],{"class":119}," pathErr ",[92,28888,1959],{"class":98},[92,28890,28891],{"class":5161},"os",[92,28893,81],{"class":119},[92,28895,28896],{"class":5161},"PathError\n",[92,28898,28899,28901,28903,28906,28909,28911,28914],{"class":94,"line":217},[92,28900,4588],{"class":98},[92,28902,28696],{"class":119},[92,28904,28905],{"class":5161},"As",[92,28907,28908],{"class":119},"(err, ",[92,28910,1807],{"class":98},[92,28912,28913],{"class":119},"pathErr) { ",[92,28915,28916],{"class":134},"// true if some error in the chain is *os.PathError\n",[92,28918,28919,28921,28923],{"class":94,"line":712},[92,28920,24353],{"class":119},[92,28922,24356],{"class":5161},[92,28924,28925],{"class":119},"(pathErr.Path)\n",[92,28927,28928],{"class":94,"line":730},[92,28929,4711],{"class":119},[242,28931,28933],{"id":28932},"custom-error-types","Custom error types",[11,28935,28936,28937,28939],{},"Any type with an ",[15,28938,28613],{}," method is an error, so you define a custom error to carry structured data callers can act on.",[83,28941,28943],{"className":24256,"code":28942,"language":24258,"meta":88,"style":88},"type ValidationError struct {\n    Field string\n    Msg   string\n}\n\nfunc (e *ValidationError) Error() string {\n    return e.Field + \": \" + e.Msg\n}\n\nfunc validate(name string) error {\n    if name == \"\" {\n        return &ValidationError{Field: \"name\", Msg: \"required\"}\n    }\n    return nil\n}\n",[15,28944,28945,28956,28963,28970,28974,28978,29002,29019,29023,29027,29046,29059,29081,29085,29091],{"__ignoreMap":88},[92,28946,28947,28949,28952,28954],{"class":94,"line":95},[92,28948,24766],{"class":98},[92,28950,28951],{"class":5161}," ValidationError",[92,28953,26399],{"class":98},[92,28955,4695],{"class":119},[92,28957,28958,28961],{"class":94,"line":106},[92,28959,28960],{"class":119},"    Field ",[92,28962,28196],{"class":98},[92,28964,28965,28968],{"class":94,"line":113},[92,28966,28967],{"class":119},"    Msg   ",[92,28969,28196],{"class":98},[92,28971,28972],{"class":94,"line":138},[92,28973,4711],{"class":119},[92,28975,28976],{"class":94,"line":143},[92,28977,110],{"emptyLinePlaceholder":109},[92,28979,28980,28982,28984,28987,28989,28992,28994,28996,28998,29000],{"class":94,"line":149},[92,28981,24321],{"class":98},[92,28983,3559],{"class":119},[92,28985,28986],{"class":27119},"e ",[92,28988,1959],{"class":98},[92,28990,28991],{"class":5161},"ValidationError",[92,28993,683],{"class":119},[92,28995,9038],{"class":5161},[92,28997,7133],{"class":119},[92,28999,376],{"class":98},[92,29001,4695],{"class":119},[92,29003,29004,29006,29009,29011,29014,29016],{"class":94,"line":155},[92,29005,5195],{"class":98},[92,29007,29008],{"class":119}," e.Field ",[92,29010,1795],{"class":98},[92,29012,29013],{"class":171}," \": \"",[92,29015,1208],{"class":98},[92,29017,29018],{"class":119}," e.Msg\n",[92,29020,29021],{"class":94,"line":161},[92,29022,4711],{"class":119},[92,29024,29025],{"class":94,"line":166},[92,29026,110],{"emptyLinePlaceholder":109},[92,29028,29029,29031,29034,29036,29038,29040,29042,29044],{"class":94,"line":187},[92,29030,24321],{"class":98},[92,29032,29033],{"class":5161}," validate",[92,29035,120],{"class":119},[92,29037,5271],{"class":27119},[92,29039,5188],{"class":98},[92,29041,683],{"class":119},[92,29043,27525],{"class":98},[92,29045,4695],{"class":119},[92,29047,29048,29050,29052,29054,29057],{"class":94,"line":217},[92,29049,9161],{"class":98},[92,29051,24446],{"class":119},[92,29053,1344],{"class":98},[92,29055,29056],{"class":171}," \"\"",[92,29058,4695],{"class":119},[92,29060,29061,29063,29065,29067,29070,29073,29076,29079],{"class":94,"line":712},[92,29062,6236],{"class":98},[92,29064,1895],{"class":98},[92,29066,28991],{"class":5161},[92,29068,29069],{"class":119},"{Field: ",[92,29071,29072],{"class":171},"\"name\"",[92,29074,29075],{"class":119},", Msg: ",[92,29077,29078],{"class":171},"\"required\"",[92,29080,4711],{"class":119},[92,29082,29083],{"class":94,"line":730},[92,29084,5104],{"class":119},[92,29086,29087,29089],{"class":94,"line":747},[92,29088,5195],{"class":98},[92,29090,27634],{"class":102},[92,29092,29093],{"class":94,"line":763},[92,29094,4711],{"class":119},[11,29096,29097],{},"When deciding between returning an error and panicking, the rule of thumb is:",[11016,29099,29100,29108,29115],{},[11019,29101,29102,29107],{},[10490,29103,29104,29105],{},"Return an ",[15,29106,27525],{}," for anything a caller could reasonably expect and handle: missing files, bad input, network failures. This is the default.",[11019,29109,29110,29114],{},[10490,29111,29112],{},[15,29113,27643],{}," only for programmer mistakes and truly unrecoverable states: an impossible switch case, a broken invariant, a nil pointer that should never be nil.",[11019,29116,29117,29121],{},[10490,29118,29119],{},[15,29120,27647],{}," at trust boundaries (an HTTP handler, a worker goroutine) so one request's panic does not crash the whole process.",[39,29123,29125],{"id":29124},"concurrency","Concurrency",[11,29127,29128,29129,29131],{},"Concurrency is built into Go rather than added by a library, which is its headline feature. The model is \"do not communicate by sharing memory; share memory by communicating,\" meaning you coordinate goroutines with channels instead of locks wherever you can. For the conceptual difference between concurrency and parallelism, the ",[23,29130,31],{"href":30}," covers it directly.",[242,29133,29135],{"id":29134},"goroutines","Goroutines",[11,29137,29138,29139,29141,29142,29144],{},"A goroutine is a function running concurrently, started by putting ",[15,29140,24258],{}," in front of a call. Goroutines are extremely cheap (a few kilobytes of stack, multiplexed onto OS threads by the runtime), so you can have hundreds of thousands. The catch is that ",[15,29143,14906],{}," does not wait for them, so you need a way to synchronize, or the program exits while goroutines are still running.",[83,29146,29148],{"className":24256,"code":29147,"language":24258,"meta":88,"style":88},"go doWork()                 // runs concurrently; main does not wait\ngo func() {                 // an anonymous goroutine\n    fmt.Println(\"in a goroutine\")\n}()\n",[15,29149,29150,29163,29175,29188],{"__ignoreMap":88},[92,29151,29152,29154,29157,29160],{"class":94,"line":95},[92,29153,24258],{"class":98},[92,29155,29156],{"class":5161}," doWork",[92,29158,29159],{"class":119},"()                 ",[92,29161,29162],{"class":134},"// runs concurrently; main does not wait\n",[92,29164,29165,29167,29169,29172],{"class":94,"line":106},[92,29166,24258],{"class":98},[92,29168,27427],{"class":98},[92,29170,29171],{"class":119},"() {                 ",[92,29173,29174],{"class":134},"// an anonymous goroutine\n",[92,29176,29177,29179,29181,29183,29186],{"class":94,"line":113},[92,29178,24353],{"class":119},[92,29180,24356],{"class":5161},[92,29182,120],{"class":119},[92,29184,29185],{"class":171},"\"in a goroutine\"",[92,29187,24307],{"class":119},[92,29189,29190],{"class":94,"line":138},[92,29191,29192],{"class":119},"}()\n",[242,29194,29196],{"id":29195},"channels","Channels",[11,29198,29199,29200,29203,29204,29207],{},"A channel is a typed conduit you send to with ",[15,29201,29202],{},"ch \u003C- v"," and receive from with ",[15,29205,29206],{},"v := \u003C-ch",". Channels come in two kinds, and the difference decides whether operations block:",[11016,29209,29210,29220],{},[11019,29211,26615,29212,29215,29216,29219],{},[10490,29213,29214],{},"unbuffered"," channel (",[15,29217,29218],{},"make(chan int)",") has no capacity: a send blocks until another goroutine receives, so it synchronizes the two sides at that moment.",[11019,29221,6686,29222,29215,29225,29228,29229,29232],{},[10490,29223,29224],{},"buffered",[15,29226,29227],{},"make(chan int, n)",") holds up to ",[15,29230,29231],{},"n"," values: a send blocks only when the buffer is full, and a receive blocks only when it is empty.",[83,29234,29236],{"className":24256,"code":29235,"language":24258,"meta":88,"style":88},"ch := make(chan int)        // unbuffered\ngo func() { ch \u003C- 42 }()    // this send blocks until the receive below runs\nv := \u003C-ch                   // 42\n\nbuf := make(chan int, 2)    // buffered, capacity 2\nbuf \u003C- 1                    // does not block\nbuf \u003C- 2                    // does not block; a third send would block\n\nclose(buf)                  // signal that no more values will be sent\nfor v := range buf {        // ranges until the channel is closed and drained\n    fmt.Println(v)          // 1, then 2\n}\n\nv, ok := \u003C-buf              // ok is false once a closed channel is drained\n",[15,29237,29238,29259,29279,29295,29299,29323,29334,29345,29349,29360,29376,29387,29391,29395],{"__ignoreMap":88},[92,29239,29240,29243,29245,29247,29249,29252,29254,29256],{"class":94,"line":95},[92,29241,29242],{"class":119},"ch ",[92,29244,24335],{"class":98},[92,29246,25855],{"class":5161},[92,29248,120],{"class":119},[92,29250,29251],{"class":98},"chan",[92,29253,5370],{"class":98},[92,29255,25511],{"class":119},[92,29257,29258],{"class":134},"// unbuffered\n",[92,29260,29261,29263,29265,29268,29271,29273,29276],{"class":94,"line":106},[92,29262,24258],{"class":98},[92,29264,27427],{"class":98},[92,29266,29267],{"class":119},"() { ch ",[92,29269,29270],{"class":98},"\u003C-",[92,29272,283],{"class":102},[92,29274,29275],{"class":119}," }()    ",[92,29277,29278],{"class":134},"// this send blocks until the receive below runs\n",[92,29280,29281,29284,29286,29289,29292],{"class":94,"line":113},[92,29282,29283],{"class":119},"v ",[92,29285,24335],{"class":98},[92,29287,29288],{"class":98}," \u003C-",[92,29290,29291],{"class":119},"ch                   ",[92,29293,29294],{"class":134},"// 42\n",[92,29296,29297],{"class":94,"line":138},[92,29298,110],{"emptyLinePlaceholder":109},[92,29300,29301,29304,29306,29308,29310,29312,29314,29316,29318,29320],{"class":94,"line":143},[92,29302,29303],{"class":119},"buf ",[92,29305,24335],{"class":98},[92,29307,25855],{"class":5161},[92,29309,120],{"class":119},[92,29311,29251],{"class":98},[92,29313,5370],{"class":98},[92,29315,195],{"class":119},[92,29317,354],{"class":102},[92,29319,24715],{"class":119},[92,29321,29322],{"class":134},"// buffered, capacity 2\n",[92,29324,29325,29327,29329,29331],{"class":94,"line":149},[92,29326,29303],{"class":119},[92,29328,29270],{"class":98},[92,29330,1849],{"class":102},[92,29332,29333],{"class":134},"                    // does not block\n",[92,29335,29336,29338,29340,29342],{"class":94,"line":155},[92,29337,29303],{"class":119},[92,29339,29270],{"class":98},[92,29341,1225],{"class":102},[92,29343,29344],{"class":134},"                    // does not block; a third send would block\n",[92,29346,29347],{"class":94,"line":161},[92,29348,110],{"emptyLinePlaceholder":109},[92,29350,29351,29354,29357],{"class":94,"line":166},[92,29352,29353],{"class":5161},"close",[92,29355,29356],{"class":119},"(buf)                  ",[92,29358,29359],{"class":134},"// signal that no more values will be sent\n",[92,29361,29362,29364,29366,29368,29370,29373],{"class":94,"line":187},[92,29363,4906],{"class":98},[92,29365,26648],{"class":119},[92,29367,24335],{"class":98},[92,29369,25121],{"class":98},[92,29371,29372],{"class":119}," buf {        ",[92,29374,29375],{"class":134},"// ranges until the channel is closed and drained\n",[92,29377,29378,29380,29382,29385],{"class":94,"line":217},[92,29379,24353],{"class":119},[92,29381,24356],{"class":5161},[92,29383,29384],{"class":119},"(v)          ",[92,29386,27485],{"class":134},[92,29388,29389],{"class":94,"line":712},[92,29390,4711],{"class":119},[92,29392,29393],{"class":94,"line":730},[92,29394,110],{"emptyLinePlaceholder":109},[92,29396,29397,29399,29401,29403,29406],{"class":94,"line":747},[92,29398,26255],{"class":119},[92,29400,24335],{"class":98},[92,29402,29288],{"class":98},[92,29404,29405],{"class":119},"buf              ",[92,29407,29408],{"class":134},"// ok is false once a closed channel is drained\n",[11,29410,29411],{},[3108,29412],{"alt":29413,"src":29414},"Producer goroutines sending values through a channel to a consumer goroutine","/post-images/go-syntax-recap/go-goroutines-channel.png",[242,29416,29417],{"id":29417},"select",[11,29419,29420,29422,29423,29425,29426,29428,29429,29432],{},[15,29421,29417],{}," waits on several channel operations at once and proceeds with whichever is ready first, picking randomly among several ready cases. A ",[15,29424,4628],{}," case makes the whole ",[15,29427,29417],{}," non-blocking, and a ",[15,29430,29431],{},"time.After"," case gives you a timeout.",[83,29434,29436],{"className":24256,"code":29435,"language":24258,"meta":88,"style":88},"select {\ncase v := \u003C-ch1:\n    fmt.Println(\"from ch1:\", v)\ncase ch2 \u003C- 99:\n    fmt.Println(\"sent to ch2\")\ncase \u003C-time.After(time.Second):\n    fmt.Println(\"timed out after 1s\")\ndefault:\n    fmt.Println(\"nothing ready right now\") // makes select non-blocking\n}\n",[15,29437,29438,29444,29457,29470,29483,29496,29511,29524,29530,29546],{"__ignoreMap":88},[92,29439,29440,29442],{"class":94,"line":95},[92,29441,29417],{"class":98},[92,29443,4695],{"class":119},[92,29445,29446,29448,29450,29452,29454],{"class":94,"line":106},[92,29447,26715],{"class":98},[92,29449,26648],{"class":119},[92,29451,24335],{"class":98},[92,29453,29288],{"class":98},[92,29455,29456],{"class":119},"ch1:\n",[92,29458,29459,29461,29463,29465,29468],{"class":94,"line":113},[92,29460,24353],{"class":119},[92,29462,24356],{"class":5161},[92,29464,120],{"class":119},[92,29466,29467],{"class":171},"\"from ch1:\"",[92,29469,28537],{"class":119},[92,29471,29472,29474,29477,29479,29481],{"class":94,"line":138},[92,29473,26715],{"class":98},[92,29475,29476],{"class":119}," ch2 ",[92,29478,29270],{"class":98},[92,29480,8597],{"class":102},[92,29482,4828],{"class":119},[92,29484,29485,29487,29489,29491,29494],{"class":94,"line":143},[92,29486,24353],{"class":119},[92,29488,24356],{"class":5161},[92,29490,120],{"class":119},[92,29492,29493],{"class":171},"\"sent to ch2\"",[92,29495,24307],{"class":119},[92,29497,29498,29500,29502,29505,29508],{"class":94,"line":149},[92,29499,26715],{"class":98},[92,29501,29288],{"class":98},[92,29503,29504],{"class":119},"time.",[92,29506,29507],{"class":5161},"After",[92,29509,29510],{"class":119},"(time.Second):\n",[92,29512,29513,29515,29517,29519,29522],{"class":94,"line":155},[92,29514,24353],{"class":119},[92,29516,24356],{"class":5161},[92,29518,120],{"class":119},[92,29520,29521],{"class":171},"\"timed out after 1s\"",[92,29523,24307],{"class":119},[92,29525,29526,29528],{"class":94,"line":161},[92,29527,4628],{"class":98},[92,29529,4828],{"class":119},[92,29531,29532,29534,29536,29538,29541,29543],{"class":94,"line":166},[92,29533,24353],{"class":119},[92,29535,24356],{"class":5161},[92,29537,120],{"class":119},[92,29539,29540],{"class":171},"\"nothing ready right now\"",[92,29542,683],{"class":119},[92,29544,29545],{"class":134},"// makes select non-blocking\n",[92,29547,29548],{"class":94,"line":187},[92,29549,4711],{"class":119},[242,29551,29553],{"id":29552},"synchronization-with-the-sync-package","Synchronization with the sync package",[11,29555,29556,29557,29560],{},"When channels are the wrong tool (usually for guarding shared state), the ",[15,29558,29559],{},"sync"," package provides classic primitives:",[11016,29562,29563,29580,29595,29601],{},[11019,29564,29565,29568,29569,29572,29573,29576,29577,81],{},[15,29566,29567],{},"sync.WaitGroup"," waits for a set of goroutines to finish: call ",[15,29570,29571],{},"Add(n)",", each goroutine calls ",[15,29574,29575],{},"Done()",", and the main goroutine calls ",[15,29578,29579],{},"Wait()",[11019,29581,29582,29584,29585,834,29588,29591,29592,81],{},[15,29583,24523],{}," gives mutual exclusion with ",[15,29586,29587],{},"Lock()",[15,29589,29590],{},"Unlock()",", usually paired with ",[15,29593,29594],{},"defer mu.Unlock()",[11019,29596,29597,29600],{},[15,29598,29599],{},"sync.RWMutex"," allows many concurrent readers or one writer.",[11019,29602,29603,29606],{},[15,29604,29605],{},"sync.Once"," runs an initialization exactly once, even under concurrent callers.",[83,29608,29610],{"className":24256,"code":29609,"language":24258,"meta":88,"style":88},"var wg sync.WaitGroup\nresults := make([]int, 5)\nfor i := range 5 {\n    wg.Add(1)\n    go func() {                 // Go 1.22+: i is per-iteration, safe to use directly\n        defer wg.Done()\n        results[i] = i * i      // distinct indices, so no lock needed here\n    }()\n}\nwg.Wait()                       // block until all five goroutines call Done\n\nvar mu sync.Mutex\nmu.Lock()\ncounter++                       // protect shared mutable state\nmu.Unlock()\n",[15,29611,29612,29626,29645,29659,29673,29685,29698,29715,29719,29723,29736,29740,29754,29764,29774],{"__ignoreMap":88},[92,29613,29614,29616,29619,29621,29623],{"class":94,"line":95},[92,29615,24414],{"class":98},[92,29617,29618],{"class":119}," wg ",[92,29620,29559],{"class":5161},[92,29622,81],{"class":119},[92,29624,29625],{"class":5161},"WaitGroup\n",[92,29627,29628,29631,29633,29635,29637,29639,29641,29643],{"class":94,"line":106},[92,29629,29630],{"class":119},"results ",[92,29632,24335],{"class":98},[92,29634,25855],{"class":5161},[92,29636,25413],{"class":119},[92,29638,370],{"class":98},[92,29640,195],{"class":119},[92,29642,1463],{"class":102},[92,29644,24307],{"class":119},[92,29646,29647,29649,29651,29653,29655,29657],{"class":94,"line":113},[92,29648,4906],{"class":98},[92,29650,25242],{"class":119},[92,29652,24335],{"class":98},[92,29654,25121],{"class":98},[92,29656,1315],{"class":102},[92,29658,4695],{"class":119},[92,29660,29661,29664,29667,29669,29671],{"class":94,"line":138},[92,29662,29663],{"class":119},"    wg.",[92,29665,29666],{"class":5161},"Add",[92,29668,120],{"class":119},[92,29670,68],{"class":102},[92,29672,24307],{"class":119},[92,29674,29675,29678,29680,29682],{"class":94,"line":143},[92,29676,29677],{"class":98},"    go",[92,29679,27427],{"class":98},[92,29681,29171],{"class":119},[92,29683,29684],{"class":134},"// Go 1.22+: i is per-iteration, safe to use directly\n",[92,29686,29687,29690,29693,29696],{"class":94,"line":149},[92,29688,29689],{"class":98},"        defer",[92,29691,29692],{"class":119}," wg.",[92,29694,29695],{"class":5161},"Done",[92,29697,27470],{"class":119},[92,29699,29700,29703,29705,29707,29709,29712],{"class":94,"line":155},[92,29701,29702],{"class":119},"        results[i] ",[92,29704,126],{"class":98},[92,29706,25242],{"class":119},[92,29708,1959],{"class":98},[92,29710,29711],{"class":119}," i      ",[92,29713,29714],{"class":134},"// distinct indices, so no lock needed here\n",[92,29716,29717],{"class":94,"line":161},[92,29718,27753],{"class":119},[92,29720,29721],{"class":94,"line":166},[92,29722,4711],{"class":119},[92,29724,29725,29728,29731,29733],{"class":94,"line":187},[92,29726,29727],{"class":119},"wg.",[92,29729,29730],{"class":5161},"Wait",[92,29732,27482],{"class":119},[92,29734,29735],{"class":134},"// block until all five goroutines call Done\n",[92,29737,29738],{"class":94,"line":217},[92,29739,110],{"emptyLinePlaceholder":109},[92,29741,29742,29744,29747,29749,29751],{"class":94,"line":712},[92,29743,24414],{"class":98},[92,29745,29746],{"class":119}," mu ",[92,29748,29559],{"class":5161},[92,29750,81],{"class":119},[92,29752,29753],{"class":5161},"Mutex\n",[92,29755,29756,29759,29762],{"class":94,"line":730},[92,29757,29758],{"class":119},"mu.",[92,29760,29761],{"class":5161},"Lock",[92,29763,27470],{"class":119},[92,29765,29766,29769,29771],{"class":94,"line":747},[92,29767,29768],{"class":119},"counter",[92,29770,4926],{"class":98},[92,29772,29773],{"class":134},"                       // protect shared mutable state\n",[92,29775,29776,29778,29781],{"class":94,"line":763},[92,29777,29758],{"class":119},[92,29779,29780],{"class":5161},"Unlock",[92,29782,27470],{"class":119},[11,29784,29785,29786,29789,29790,29793],{},"Run tests and programs with the ",[15,29787,29788],{},"-race"," flag (",[15,29791,29792],{},"go run -race .",") to catch data races, where two goroutines touch the same memory and at least one writes; the race detector is the fastest way to find these bugs.",[39,29795,29797],{"id":29796},"generics","Generics",[11,29799,29800,29801,29804,29805,29807,29808,29811,29812,29814,29815,29818,29819,29821],{},"Since Go 1.18 functions and types can take ",[1511,29802,29803],{},"type parameters",", letting you write one implementation that works for many types with full type safety, instead of falling back to ",[15,29806,28404],{}," and type assertions. A type parameter has a ",[1511,29809,29810],{},"constraint"," that limits which types are allowed: ",[15,29813,28404],{}," allows anything, ",[15,29816,29817],{},"comparable"," allows types usable with ",[15,29820,1344],{},", and you can define your own constraint as an interface of allowed types.",[83,29823,29825],{"className":24256,"code":29824,"language":24258,"meta":88,"style":88},"// A generic function: works for any element type.\nfunc Map[T, U any](s []T, f func(T) U) []U {\n    out := make([]U, len(s))\n    for i, v := range s {\n        out[i] = f(v)\n    }\n    return out\n}\ndoubled := Map([]int{1, 2, 3}, func(n int) int { return n * 2 }) // [2, 4, 6]\n\n// A custom constraint: the ~ allows named types whose underlying type matches.\ntype Number interface {\n    ~int | ~int64 | ~float64\n}\n\nfunc Sum[T Number](s []T) T {\n    var total T\n    for _, v := range s {\n        total += v\n    }\n    return total\n}\nSum([]int{1, 2, 3})          // 6\n",[15,29826,29827,29832,29884,29904,29917,29929,29933,29940,29944,29999,30003,30008,30019,30034,30038,30042,30069,30080,30093,30102,30106,30112,30116],{"__ignoreMap":88},[92,29828,29829],{"class":94,"line":95},[92,29830,29831],{"class":134},"// A generic function: works for any element type.\n",[92,29833,29834,29836,29839,29841,29844,29846,29849,29852,29855,29858,29860,29862,29864,29867,29869,29871,29873,29875,29877,29880,29882],{"class":94,"line":106},[92,29835,24321],{"class":98},[92,29837,29838],{"class":5161}," Map",[92,29840,1841],{"class":119},[92,29842,29843],{"class":27119},"T",[92,29845,195],{"class":119},[92,29847,29848],{"class":27119},"U",[92,29850,29851],{"class":5161}," any",[92,29853,29854],{"class":119},"](",[92,29856,29857],{"class":27119},"s",[92,29859,24705],{"class":119},[92,29861,29843],{"class":5161},[92,29863,195],{"class":119},[92,29865,29866],{"class":27119},"f",[92,29868,27427],{"class":98},[92,29870,120],{"class":119},[92,29872,29843],{"class":5161},[92,29874,683],{"class":119},[92,29876,29848],{"class":5161},[92,29878,29879],{"class":119},") []",[92,29881,29848],{"class":5161},[92,29883,4695],{"class":119},[92,29885,29886,29889,29891,29893,29895,29897,29899,29901],{"class":94,"line":113},[92,29887,29888],{"class":119},"    out ",[92,29890,24335],{"class":98},[92,29892,25855],{"class":5161},[92,29894,25413],{"class":119},[92,29896,29848],{"class":5161},[92,29898,195],{"class":119},[92,29900,25086],{"class":5161},[92,29902,29903],{"class":119},"(s))\n",[92,29905,29906,29908,29910,29912,29914],{"class":94,"line":138},[92,29907,5963],{"class":98},[92,29909,26915],{"class":119},[92,29911,24335],{"class":98},[92,29913,25121],{"class":98},[92,29915,29916],{"class":119}," s {\n",[92,29918,29919,29922,29924,29927],{"class":94,"line":143},[92,29920,29921],{"class":119},"        out[i] ",[92,29923,126],{"class":98},[92,29925,29926],{"class":5161}," f",[92,29928,26674],{"class":119},[92,29930,29931],{"class":94,"line":149},[92,29932,5104],{"class":119},[92,29934,29935,29937],{"class":94,"line":155},[92,29936,5195],{"class":98},[92,29938,29939],{"class":119}," out\n",[92,29941,29942],{"class":94,"line":161},[92,29943,4711],{"class":119},[92,29945,29946,29949,29951,29953,29955,29957,29959,29961,29963,29965,29967,29969,29971,29973,29975,29977,29979,29981,29983,29985,29987,29990,29992,29994,29997],{"class":94,"line":166},[92,29947,29948],{"class":119},"doubled ",[92,29950,24335],{"class":98},[92,29952,29838],{"class":5161},[92,29954,25413],{"class":119},[92,29956,370],{"class":98},[92,29958,25418],{"class":119},[92,29960,68],{"class":102},[92,29962,195],{"class":119},[92,29964,354],{"class":102},[92,29966,195],{"class":119},[92,29968,1448],{"class":102},[92,29970,25429],{"class":119},[92,29972,24321],{"class":98},[92,29974,120],{"class":119},[92,29976,29231],{"class":27119},[92,29978,5370],{"class":98},[92,29980,683],{"class":119},[92,29982,370],{"class":98},[92,29984,28025],{"class":119},[92,29986,27101],{"class":98},[92,29988,29989],{"class":119}," n ",[92,29991,1959],{"class":98},[92,29993,1225],{"class":102},[92,29995,29996],{"class":119}," }) ",[92,29998,8462],{"class":134},[92,30000,30001],{"class":94,"line":187},[92,30002,110],{"emptyLinePlaceholder":109},[92,30004,30005],{"class":94,"line":217},[92,30006,30007],{"class":134},"// A custom constraint: the ~ allows named types whose underlying type matches.\n",[92,30009,30010,30012,30015,30017],{"class":94,"line":712},[92,30011,24766],{"class":98},[92,30013,30014],{"class":5161}," Number",[92,30016,28281],{"class":98},[92,30018,4695],{"class":119},[92,30020,30021,30024,30026,30029,30031],{"class":94,"line":730},[92,30022,30023],{"class":98},"    ~int",[92,30025,1909],{"class":98},[92,30027,30028],{"class":98}," ~int64",[92,30030,1909],{"class":98},[92,30032,30033],{"class":98}," ~float64\n",[92,30035,30036],{"class":94,"line":747},[92,30037,4711],{"class":119},[92,30039,30040],{"class":94,"line":763},[92,30041,110],{"emptyLinePlaceholder":109},[92,30043,30044,30046,30049,30051,30053,30055,30057,30059,30061,30063,30065,30067],{"class":94,"line":780},[92,30045,24321],{"class":98},[92,30047,30048],{"class":5161}," Sum",[92,30050,1841],{"class":119},[92,30052,29843],{"class":27119},[92,30054,30014],{"class":5161},[92,30056,29854],{"class":119},[92,30058,29857],{"class":27119},[92,30060,24705],{"class":119},[92,30062,29843],{"class":5161},[92,30064,683],{"class":119},[92,30066,29843],{"class":5161},[92,30068,4695],{"class":119},[92,30070,30071,30074,30077],{"class":94,"line":785},[92,30072,30073],{"class":98},"    var",[92,30075,30076],{"class":119}," total ",[92,30078,30079],{"class":5161},"T\n",[92,30081,30082,30084,30087,30089,30091],{"class":94,"line":2585},[92,30083,5963],{"class":98},[92,30085,30086],{"class":119}," _, v ",[92,30088,24335],{"class":98},[92,30090,25121],{"class":98},[92,30092,29916],{"class":119},[92,30094,30095,30097,30099],{"class":94,"line":2605},[92,30096,27332],{"class":119},[92,30098,1182],{"class":98},[92,30100,30101],{"class":119}," v\n",[92,30103,30104],{"class":94,"line":2634},[92,30105,5104],{"class":119},[92,30107,30108,30110],{"class":94,"line":2651},[92,30109,5195],{"class":98},[92,30111,27348],{"class":119},[92,30113,30114],{"class":94,"line":2671},[92,30115,4711],{"class":119},[92,30117,30118,30121,30123,30125,30127,30129,30131,30133,30135,30137,30140],{"class":94,"line":2676},[92,30119,30120],{"class":5161},"Sum",[92,30122,25413],{"class":119},[92,30124,370],{"class":98},[92,30126,25418],{"class":119},[92,30128,68],{"class":102},[92,30130,195],{"class":119},[92,30132,354],{"class":102},[92,30134,195],{"class":119},[92,30136,1448],{"class":102},[92,30138,30139],{"class":119},"})          ",[92,30141,5411],{"class":134},[39,30143,9292],{"id":9291},[242,30145,30147],{"id":30146},"formatting-and-printing-with-fmt","Formatting and printing with fmt",[11,30149,30150,30152,30153,30155,30156,30158,30159,30162],{},[15,30151,24288],{}," handles formatted I/O. ",[15,30154,24356],{}," prints values separated by spaces, ",[15,30157,25134],{}," uses a format string, and ",[15,30160,30161],{},"Sprintf"," returns the formatted string instead of printing it. The verbs you actually use:",[11016,30164,30165,30178,30184,30201,30214,30232],{},[11019,30166,30167,30169,30170,30173,30174,30177],{},[15,30168,27739],{}," default format, ",[15,30171,30172],{},"%+v"," adds struct field names, ",[15,30175,30176],{},"%#v"," prints Go syntax.",[11019,30179,30180,30183],{},[15,30181,30182],{},"%T"," the value's type.",[11019,30185,30186,30188,30189,30192,30193,30196,30197,30200],{},[15,30187,25141],{}," integer, ",[15,30190,30191],{},"%b"," binary, ",[15,30194,30195],{},"%x"," hex, ",[15,30198,30199],{},"%o"," octal.",[11019,30202,30203,30206,30207,30210,30211,30213],{},[15,30204,30205],{},"%s"," string, ",[15,30208,30209],{},"%q"," a double-quoted string, ",[15,30212,25146],{}," a rune as a character.",[11019,30215,30216,30219,30220,30223,30224,30227,30228,30231],{},[15,30217,30218],{},"%f"," float, ",[15,30221,30222],{},"%.2f"," fixed precision, ",[15,30225,30226],{},"%g"," compact float, ",[15,30229,30230],{},"%e"," scientific.",[11019,30233,30234,30237,30238,30241],{},[15,30235,30236],{},"%t"," boolean, ",[15,30239,30240],{},"%p"," pointer.",[83,30243,30245],{"className":24256,"code":30244,"language":24258,"meta":88,"style":88},"fmt.Printf(\"%s is %d (%.1f%%)\\n\", \"cpu\", 3, 42.5) // cpu is 3 (42.5%)\nfmt.Printf(\"%+v\\n\", User{ID: 1, Name: \"Ada\"})     // {ID:1 Name:Ada Email:}\ns := fmt.Sprintf(\"%03d\", 7)                        // \"007\"\n",[15,30246,30247,30293,30326],{"__ignoreMap":88},[92,30248,30249,30252,30254,30256,30258,30260,30262,30264,30266,30269,30271,30273,30275,30277,30280,30282,30284,30286,30288,30290],{"class":94,"line":95},[92,30250,30251],{"class":119},"fmt.",[92,30253,25134],{"class":5161},[92,30255,120],{"class":119},[92,30257,178],{"class":171},[92,30259,30205],{"class":102},[92,30261,987],{"class":171},[92,30263,25141],{"class":102},[92,30265,3559],{"class":171},[92,30267,30268],{"class":102},"%.1f%%",[92,30270,5182],{"class":171},[92,30272,175],{"class":102},[92,30274,178],{"class":171},[92,30276,195],{"class":119},[92,30278,30279],{"class":171},"\"cpu\"",[92,30281,195],{"class":119},[92,30283,1448],{"class":102},[92,30285,195],{"class":119},[92,30287,2747],{"class":102},[92,30289,683],{"class":119},[92,30291,30292],{"class":134},"// cpu is 3 (42.5%)\n",[92,30294,30295,30297,30299,30301,30303,30306,30308,30310,30312,30314,30316,30318,30320,30323],{"class":94,"line":106},[92,30296,30251],{"class":119},[92,30298,25134],{"class":5161},[92,30300,120],{"class":119},[92,30302,178],{"class":171},[92,30304,30305],{"class":102},"%+v\\n",[92,30307,178],{"class":171},[92,30309,195],{"class":119},[92,30311,27917],{"class":5161},[92,30313,27862],{"class":119},[92,30315,68],{"class":102},[92,30317,27867],{"class":119},[92,30319,27870],{"class":171},[92,30321,30322],{"class":119},"})     ",[92,30324,30325],{"class":134},"// {ID:1 Name:Ada Email:}\n",[92,30327,30328,30330,30332,30334,30336,30338,30340,30343,30345,30347,30349,30352],{"class":94,"line":113},[92,30329,24723],{"class":119},[92,30331,24335],{"class":98},[92,30333,27605],{"class":119},[92,30335,30161],{"class":5161},[92,30337,120],{"class":119},[92,30339,178],{"class":171},[92,30341,30342],{"class":102},"%03d",[92,30344,178],{"class":171},[92,30346,195],{"class":119},[92,30348,1205],{"class":102},[92,30350,30351],{"class":119},")                        ",[92,30353,30354],{"class":134},"// \"007\"\n",[242,30356,30358],{"id":30357},"fast-input-and-output","Fast input and output",[11,30360,30361,30362,30365,30366,30369,30370,30373,30374,81],{},"Reading input with ",[15,30363,30364],{},"fmt.Scan"," is fine for a few values but slow for large inputs, which matters in timed rounds. The fast idiom is a buffered ",[15,30367,30368],{},"bufio.Scanner"," for reading and a ",[15,30371,30372],{},"bufio.Writer"," for writing, flushed with a deferred ",[15,30375,30376],{},"Flush",[83,30378,30380],{"className":24256,"code":30379,"language":24258,"meta":88,"style":88},"reader := bufio.NewScanner(os.Stdin)\nreader.Buffer(make([]byte, 1024*1024), 1024*1024) // allow long lines\nreader.Split(bufio.ScanWords)                     // token-by-token; default is by line\nreader.Scan()\nn, _ := strconv.Atoi(reader.Text())               // read one integer token\n\nwriter := bufio.NewWriter(os.Stdout)\ndefer writer.Flush()                              // MUST flush, or output is lost\nfmt.Fprintln(writer, \"answer:\", n)\n",[15,30381,30382,30398,30437,30449,30458,30482,30486,30501,30516],{"__ignoreMap":88},[92,30383,30384,30387,30389,30392,30395],{"class":94,"line":95},[92,30385,30386],{"class":119},"reader ",[92,30388,24335],{"class":98},[92,30390,30391],{"class":119}," bufio.",[92,30393,30394],{"class":5161},"NewScanner",[92,30396,30397],{"class":119},"(os.Stdin)\n",[92,30399,30400,30403,30406,30408,30410,30412,30414,30416,30419,30421,30423,30426,30428,30430,30432,30434],{"class":94,"line":106},[92,30401,30402],{"class":119},"reader.",[92,30404,30405],{"class":5161},"Buffer",[92,30407,120],{"class":119},[92,30409,26148],{"class":5161},[92,30411,25413],{"class":119},[92,30413,24607],{"class":98},[92,30415,195],{"class":119},[92,30417,30418],{"class":102},"1024",[92,30420,1959],{"class":98},[92,30422,30418],{"class":102},[92,30424,30425],{"class":119},"), ",[92,30427,30418],{"class":102},[92,30429,1959],{"class":98},[92,30431,30418],{"class":102},[92,30433,683],{"class":119},[92,30435,30436],{"class":134},"// allow long lines\n",[92,30438,30439,30441,30443,30446],{"class":94,"line":113},[92,30440,30402],{"class":119},[92,30442,25387],{"class":5161},[92,30444,30445],{"class":119},"(bufio.ScanWords)                     ",[92,30447,30448],{"class":134},"// token-by-token; default is by line\n",[92,30450,30451,30453,30456],{"class":94,"line":138},[92,30452,30402],{"class":119},[92,30454,30455],{"class":5161},"Scan",[92,30457,27470],{"class":119},[92,30459,30460,30463,30465,30468,30470,30473,30476,30479],{"class":94,"line":143},[92,30461,30462],{"class":119},"n, _ ",[92,30464,24335],{"class":98},[92,30466,30467],{"class":119}," strconv.",[92,30469,25548],{"class":5161},[92,30471,30472],{"class":119},"(reader.",[92,30474,30475],{"class":5161},"Text",[92,30477,30478],{"class":119},"())               ",[92,30480,30481],{"class":134},"// read one integer token\n",[92,30483,30484],{"class":94,"line":149},[92,30485,110],{"emptyLinePlaceholder":109},[92,30487,30488,30491,30493,30495,30498],{"class":94,"line":155},[92,30489,30490],{"class":119},"writer ",[92,30492,24335],{"class":98},[92,30494,30391],{"class":119},[92,30496,30497],{"class":5161},"NewWriter",[92,30499,30500],{"class":119},"(os.Stdout)\n",[92,30502,30503,30505,30508,30510,30513],{"class":94,"line":161},[92,30504,27494],{"class":98},[92,30506,30507],{"class":119}," writer.",[92,30509,30376],{"class":5161},[92,30511,30512],{"class":119},"()                              ",[92,30514,30515],{"class":134},"// MUST flush, or output is lost\n",[92,30517,30518,30520,30523,30526,30529],{"class":94,"line":166},[92,30519,30251],{"class":119},[92,30521,30522],{"class":5161},"Fprintln",[92,30524,30525],{"class":119},"(writer, ",[92,30527,30528],{"class":171},"\"answer:\"",[92,30530,30531],{"class":119},", n)\n",[242,30533,4052],{"id":4051},[11,30535,30536,30537,30540,30541,30543],{},"Modern code sorts with the generic ",[15,30538,30539],{},"slices"," package, while a lot of existing code uses the older ",[15,30542,4099],{}," package; both are worth recognizing.",[83,30545,30547],{"className":24256,"code":30546,"language":24258,"meta":88,"style":88},"slices.Sort(nums)                                 // ascending, in place (preferred)\nslices.SortFunc(people, func(a, b Person) int {   // custom order: return \u003C0, 0, >0\n    return cmp.Compare(a.Age, b.Age)\n})\n\nsort.Ints(nums)                                   // the older API\nsort.Slice(people, func(i, j int) bool {          // less-than comparator\n    return people[i].Age \u003C people[j].Age\n})\n",[15,30548,30549,30561,30594,30607,30612,30616,30630,30662,30674],{"__ignoreMap":88},[92,30550,30551,30553,30555,30558],{"class":94,"line":95},[92,30552,26459],{"class":119},[92,30554,26462],{"class":5161},[92,30556,30557],{"class":119},"(nums)                                 ",[92,30559,30560],{"class":134},"// ascending, in place (preferred)\n",[92,30562,30563,30565,30568,30571,30573,30575,30577,30579,30581,30584,30586,30588,30591],{"class":94,"line":106},[92,30564,26459],{"class":119},[92,30566,30567],{"class":5161},"SortFunc",[92,30569,30570],{"class":119},"(people, ",[92,30572,24321],{"class":98},[92,30574,120],{"class":119},[92,30576,23],{"class":27119},[92,30578,195],{"class":119},[92,30580,27124],{"class":27119},[92,30582,30583],{"class":5161}," Person",[92,30585,683],{"class":119},[92,30587,370],{"class":98},[92,30589,30590],{"class":119}," {   ",[92,30592,30593],{"class":134},"// custom order: return \u003C0, 0, >0\n",[92,30595,30596,30598,30601,30604],{"class":94,"line":113},[92,30597,5195],{"class":98},[92,30599,30600],{"class":119}," cmp.",[92,30602,30603],{"class":5161},"Compare",[92,30605,30606],{"class":119},"(a.Age, b.Age)\n",[92,30608,30609],{"class":94,"line":138},[92,30610,30611],{"class":119},"})\n",[92,30613,30614],{"class":94,"line":143},[92,30615,110],{"emptyLinePlaceholder":109},[92,30617,30618,30621,30624,30627],{"class":94,"line":149},[92,30619,30620],{"class":119},"sort.",[92,30622,30623],{"class":5161},"Ints",[92,30625,30626],{"class":119},"(nums)                                   ",[92,30628,30629],{"class":134},"// the older API\n",[92,30631,30632,30634,30637,30639,30641,30643,30646,30648,30651,30653,30655,30657,30659],{"class":94,"line":155},[92,30633,30620],{"class":119},[92,30635,30636],{"class":5161},"Slice",[92,30638,30570],{"class":119},[92,30640,24321],{"class":98},[92,30642,120],{"class":119},[92,30644,30645],{"class":27119},"i",[92,30647,195],{"class":119},[92,30649,30650],{"class":27119},"j",[92,30652,5370],{"class":98},[92,30654,683],{"class":119},[92,30656,379],{"class":98},[92,30658,7117],{"class":119},[92,30660,30661],{"class":134},"// less-than comparator\n",[92,30663,30664,30666,30669,30671],{"class":94,"line":161},[92,30665,5195],{"class":98},[92,30667,30668],{"class":119}," people[i].Age ",[92,30670,4671],{"class":98},[92,30672,30673],{"class":119}," people[j].Age\n",[92,30675,30676],{"class":94,"line":166},[92,30677,30611],{"class":119},[242,30679,30681],{"id":30680},"heaps-and-other-containers","Heaps and other containers",[11,30683,30684,30685,30688],{},"For priority-queue problems, ",[15,30686,30687],{},"container/heap"," turns any type that implements its interface into a heap. It is more verbose than other languages' heaps because you supply the ordering, but the pattern is fixed and worth memorizing.",[83,30690,30692],{"className":24256,"code":30691,"language":24258,"meta":88,"style":88},"type IntHeap []int\n\nfunc (h IntHeap) Len() int           { return len(h) }\nfunc (h IntHeap) Less(i, j int) bool { return h[i] \u003C h[j] } // \u003C gives a min-heap\nfunc (h IntHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }\nfunc (h *IntHeap) Push(x any)        { *h = append(*h, x.(int)) }\nfunc (h *IntHeap) Pop() any {\n    old := *h\n    n := len(old)\n    x := old[n-1]\n    *h = old[:n-1]\n    return x\n}\n\nh := &IntHeap{5, 1, 3}\nheap.Init(h)              // establish the heap invariant\nheap.Push(h, 2)\nheap.Pop(h)               // 1 (the smallest, because Less uses \u003C)\n",[15,30693,30694,30705,30709,30741,30785,30818,30864,30887,30899,30911,30926,30944,30950,30954,30958,30982,30996,31009],{"__ignoreMap":88},[92,30695,30696,30698,30701,30703],{"class":94,"line":95},[92,30697,24766],{"class":98},[92,30699,30700],{"class":5161}," IntHeap",[92,30702,24705],{"class":119},[92,30704,26018],{"class":98},[92,30706,30707],{"class":94,"line":106},[92,30708,110],{"emptyLinePlaceholder":109},[92,30710,30711,30713,30715,30718,30721,30723,30726,30728,30730,30733,30735,30738],{"class":94,"line":113},[92,30712,24321],{"class":98},[92,30714,3559],{"class":119},[92,30716,30717],{"class":27119},"h ",[92,30719,30720],{"class":5161},"IntHeap",[92,30722,683],{"class":119},[92,30724,30725],{"class":5161},"Len",[92,30727,7133],{"class":119},[92,30729,370],{"class":98},[92,30731,30732],{"class":119},"           { ",[92,30734,27101],{"class":98},[92,30736,30737],{"class":5161}," len",[92,30739,30740],{"class":119},"(h) }\n",[92,30742,30743,30745,30747,30749,30751,30753,30756,30758,30760,30762,30764,30766,30768,30770,30772,30774,30777,30779,30782],{"class":94,"line":138},[92,30744,24321],{"class":98},[92,30746,3559],{"class":119},[92,30748,30717],{"class":27119},[92,30750,30720],{"class":5161},[92,30752,683],{"class":119},[92,30754,30755],{"class":5161},"Less",[92,30757,120],{"class":119},[92,30759,30645],{"class":27119},[92,30761,195],{"class":119},[92,30763,30650],{"class":27119},[92,30765,5370],{"class":98},[92,30767,683],{"class":119},[92,30769,379],{"class":98},[92,30771,28025],{"class":119},[92,30773,27101],{"class":98},[92,30775,30776],{"class":119}," h[i] ",[92,30778,4671],{"class":98},[92,30780,30781],{"class":119}," h[j] } ",[92,30783,30784],{"class":134},"// \u003C gives a min-heap\n",[92,30786,30787,30789,30791,30793,30795,30797,30800,30802,30804,30806,30808,30810,30813,30815],{"class":94,"line":143},[92,30788,24321],{"class":98},[92,30790,3559],{"class":119},[92,30792,30717],{"class":27119},[92,30794,30720],{"class":5161},[92,30796,683],{"class":119},[92,30798,30799],{"class":5161},"Swap",[92,30801,120],{"class":119},[92,30803,30645],{"class":27119},[92,30805,195],{"class":119},[92,30807,30650],{"class":27119},[92,30809,5370],{"class":98},[92,30811,30812],{"class":119},")      { h[i], h[j] ",[92,30814,126],{"class":98},[92,30816,30817],{"class":119}," h[j], h[i] }\n",[92,30819,30820,30822,30824,30826,30828,30830,30832,30835,30837,30839,30841,30844,30846,30848,30850,30852,30854,30856,30859,30861],{"class":94,"line":149},[92,30821,24321],{"class":98},[92,30823,3559],{"class":119},[92,30825,30717],{"class":27119},[92,30827,1959],{"class":98},[92,30829,30720],{"class":5161},[92,30831,683],{"class":119},[92,30833,30834],{"class":5161},"Push",[92,30836,120],{"class":119},[92,30838,27205],{"class":27119},[92,30840,29851],{"class":5161},[92,30842,30843],{"class":119},")        { ",[92,30845,1959],{"class":98},[92,30847,30717],{"class":119},[92,30849,126],{"class":98},[92,30851,25759],{"class":5161},[92,30853,120],{"class":119},[92,30855,1959],{"class":98},[92,30857,30858],{"class":119},"h, x.(",[92,30860,370],{"class":98},[92,30862,30863],{"class":119},")) }\n",[92,30865,30866,30868,30870,30872,30874,30876,30878,30881,30883,30885],{"class":94,"line":155},[92,30867,24321],{"class":98},[92,30869,3559],{"class":119},[92,30871,30717],{"class":27119},[92,30873,1959],{"class":98},[92,30875,30720],{"class":5161},[92,30877,683],{"class":119},[92,30879,30880],{"class":5161},"Pop",[92,30882,7133],{"class":119},[92,30884,28404],{"class":5161},[92,30886,4695],{"class":119},[92,30888,30889,30892,30894,30896],{"class":94,"line":161},[92,30890,30891],{"class":119},"    old ",[92,30893,24335],{"class":98},[92,30895,7352],{"class":98},[92,30897,30898],{"class":119},"h\n",[92,30900,30901,30904,30906,30908],{"class":94,"line":166},[92,30902,30903],{"class":119},"    n ",[92,30905,24335],{"class":98},[92,30907,30737],{"class":5161},[92,30909,30910],{"class":119},"(old)\n",[92,30912,30913,30915,30917,30920,30922,30924],{"class":94,"line":187},[92,30914,27223],{"class":119},[92,30916,24335],{"class":98},[92,30918,30919],{"class":119}," old[n",[92,30921,1966],{"class":98},[92,30923,68],{"class":102},[92,30925,13109],{"class":119},[92,30927,30928,30931,30933,30935,30938,30940,30942],{"class":94,"line":217},[92,30929,30930],{"class":98},"    *",[92,30932,30717],{"class":119},[92,30934,126],{"class":98},[92,30936,30937],{"class":119}," old[:n",[92,30939,1966],{"class":98},[92,30941,68],{"class":102},[92,30943,13109],{"class":119},[92,30945,30946,30948],{"class":94,"line":712},[92,30947,5195],{"class":98},[92,30949,27250],{"class":119},[92,30951,30952],{"class":94,"line":730},[92,30953,4711],{"class":119},[92,30955,30956],{"class":94,"line":747},[92,30957,110],{"emptyLinePlaceholder":109},[92,30959,30960,30962,30964,30966,30968,30970,30972,30974,30976,30978,30980],{"class":94,"line":763},[92,30961,30717],{"class":119},[92,30963,24335],{"class":98},[92,30965,1895],{"class":98},[92,30967,30720],{"class":5161},[92,30969,25418],{"class":119},[92,30971,1463],{"class":102},[92,30973,195],{"class":119},[92,30975,68],{"class":102},[92,30977,195],{"class":119},[92,30979,1448],{"class":102},[92,30981,4711],{"class":119},[92,30983,30984,30987,30990,30993],{"class":94,"line":780},[92,30985,30986],{"class":119},"heap.",[92,30988,30989],{"class":5161},"Init",[92,30991,30992],{"class":119},"(h)              ",[92,30994,30995],{"class":134},"// establish the heap invariant\n",[92,30997,30998,31000,31002,31005,31007],{"class":94,"line":785},[92,30999,30986],{"class":119},[92,31001,30834],{"class":5161},[92,31003,31004],{"class":119},"(h, ",[92,31006,354],{"class":102},[92,31008,24307],{"class":119},[92,31010,31011,31013,31015,31018],{"class":94,"line":2585},[92,31012,30986],{"class":119},[92,31014,30880],{"class":5161},[92,31016,31017],{"class":119},"(h)               ",[92,31019,31020],{"class":134},"// 1 (the smallest, because Less uses \u003C)\n",[242,31022,31024],{"id":31023},"math-and-randomness","Math and randomness",[83,31026,31028],{"className":24256,"code":31027,"language":24258,"meta":88,"style":88},"math.Abs(-3.5)           // 3.5 (operates on float64)\nmath.Sqrt(144)           // 12\nmath.Pow(2, 10)          // 1024\nmath.MaxInt, math.MinInt // integer bounds\nmath.Inf(1)              // positive infinity\nrand.Intn(6)             // a pseudo-random int in [0, 6)\n",[15,31029,31030,31050,31066,31086,31094,31110],{"__ignoreMap":88},[92,31031,31032,31035,31038,31040,31042,31045,31047],{"class":94,"line":95},[92,31033,31034],{"class":119},"math.",[92,31036,31037],{"class":5161},"Abs",[92,31039,120],{"class":119},[92,31041,1966],{"class":98},[92,31043,31044],{"class":102},"3.5",[92,31046,25643],{"class":119},[92,31048,31049],{"class":134},"// 3.5 (operates on float64)\n",[92,31051,31052,31054,31057,31059,31061,31063],{"class":94,"line":106},[92,31053,31034],{"class":119},[92,31055,31056],{"class":5161},"Sqrt",[92,31058,120],{"class":119},[92,31060,9523],{"class":102},[92,31062,25643],{"class":119},[92,31064,31065],{"class":134},"// 12\n",[92,31067,31068,31070,31073,31075,31077,31079,31081,31083],{"class":94,"line":113},[92,31069,31034],{"class":119},[92,31071,31072],{"class":5161},"Pow",[92,31074,120],{"class":119},[92,31076,354],{"class":102},[92,31078,195],{"class":119},[92,31080,4419],{"class":102},[92,31082,25400],{"class":119},[92,31084,31085],{"class":134},"// 1024\n",[92,31087,31088,31091],{"class":94,"line":138},[92,31089,31090],{"class":119},"math.MaxInt, math.MinInt ",[92,31092,31093],{"class":134},"// integer bounds\n",[92,31095,31096,31098,31101,31103,31105,31107],{"class":94,"line":143},[92,31097,31034],{"class":119},[92,31099,31100],{"class":5161},"Inf",[92,31102,120],{"class":119},[92,31104,68],{"class":102},[92,31106,25533],{"class":119},[92,31108,31109],{"class":134},"// positive infinity\n",[92,31111,31112,31115,31118,31120,31122,31125],{"class":94,"line":149},[92,31113,31114],{"class":119},"rand.",[92,31116,31117],{"class":5161},"Intn",[92,31119,120],{"class":119},[92,31121,1235],{"class":102},[92,31123,31124],{"class":119},")             ",[92,31126,31127],{"class":134},"// a pseudo-random int in [0, 6)\n",[39,31129,31131],{"id":31130},"sharp-edges","Sharp Edges",[11,31133,31134],{},"A handful of Go behaviors reliably catch both newcomers and returning developers. Each item below pairs the trap with its fix.",[11016,31136,31137,31153,31169,31187,31203,31212,31233,31253,31259],{},[11019,31138,31139,31142,31143,31146,31147,31149,31150,31152],{},[10490,31140,31141],{},"Nil maps panic on write."," A map declared as ",[15,31144,31145],{},"var m map[string]int"," is nil, and assigning to it crashes; initialize it with ",[15,31148,26148],{}," or a literal first. Nil slices are the exception, since you can ",[15,31151,25814],{}," to them directly.",[11019,31154,31155,31158,31159,31161,31162,31164,31165,31168],{},[10490,31156,31157],{},"Slices share a backing array."," A sub-slice points into the same memory, so writes leak across both views, and ",[15,31160,25814],{}," may quietly reallocate. Always reassign ",[15,31163,25828],{},", and reach for ",[15,31166,31167],{},"slices.Clone"," when you need an independent copy.",[11019,31170,31171,31176,31177,195,31180,31183,31184,81],{},[10490,31172,31173,31175],{},[15,31174,3942],{}," copies each element."," In ",[15,31178,31179],{},"for _, v := range s",[15,31181,31182],{},"v"," is a copy, so writing to it changes nothing. Index the slice instead: ",[15,31185,31186],{},"for i := range s { s[i] = ... }",[11019,31188,31189,31192,31193,31195,31196,31199,31200,31202],{},[10490,31190,31191],{},"A typed nil is not a nil interface."," Returning a nil pointer as an ",[15,31194,27525],{}," produces an interface that still carries a type, so the caller's ",[15,31197,31198],{},"err != nil"," is true. Return a literal ",[15,31201,24556],{}," on the success path.",[11019,31204,31205,31208,31209,31211],{},[10490,31206,31207],{},"Map iteration order is randomized."," Go shuffles ",[15,31210,3942],{}," order over a map on every run, so never depend on it. When you need determinism, collect the keys, sort them, and iterate that slice.",[11019,31213,31214,1644,31217,987,31220,31222,31223,987,31226,31229,31230,81],{},[10490,31215,31216],{},"Integer math has sharp corners.",[15,31218,31219],{},"7 / 2",[15,31221,1448],{}," because both operands are ints, integer divide-by-zero panics at runtime, and overflow wraps silently (",[15,31224,31225],{},"int8(127) + 1",[15,31227,31228],{},"-128","). Widen the type, or reach for ",[15,31231,31232],{},"math/big",[11019,31234,31235,31240,31241,195,31243,31246,31247,31249,31250,31252],{},[10490,31236,31237,31239],{},[15,31238,1344],{}," misses wrapped errors."," Once an error is wrapped with ",[15,31242,28729],{},[15,31244,31245],{},"err == ErrNotFound"," is false. Use ",[15,31248,28750],{}," for sentinel values and ",[15,31251,28756],{}," for error types, both of which walk the wrap chain.",[11019,31254,31255,31258],{},[10490,31256,31257],{},"Unbuffered channels deadlock alone."," A send blocks until another goroutine receives, so sending from the only running goroutine hangs the whole program. Make sure a receiver exists, or give the channel a buffer.",[11019,31260,31261,31264,31265,31268],{},[10490,31262,31263],{},"Unused imports and variables fail the build."," Go treats them as errors, not warnings. Discard a value with the blank identifier ",[15,31266,31267],{},"_",", and delete any import you are not using.",[10887,31270,31271],{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}",{"title":88,"searchDepth":106,"depth":106,"links":31273},[31274,31275,31282,31283,31288,31296,31300,31305,31312,31317,31323,31324,31331],{"id":24233,"depth":106,"text":24234},{"id":239,"depth":106,"text":240,"children":31276},[31277,31278,31279,31280,31281],{"id":244,"depth":113,"text":245},{"id":24512,"depth":113,"text":24513},{"id":24562,"depth":113,"text":24563},{"id":24634,"depth":113,"text":24635},{"id":24759,"depth":113,"text":24760},{"id":1154,"depth":106,"text":1155},{"id":25045,"depth":106,"text":25046,"children":31284},[31285,31286,31287],{"id":25049,"depth":113,"text":25050},{"id":25179,"depth":113,"text":25180},{"id":25300,"depth":113,"text":25301},{"id":25663,"depth":106,"text":25664,"children":31289},[31290,31291,31292,31293,31294,31295],{"id":25667,"depth":113,"text":25668},{"id":25794,"depth":113,"text":25795},{"id":25840,"depth":113,"text":25841},{"id":26040,"depth":113,"text":26041},{"id":26137,"depth":113,"text":26138},{"id":26437,"depth":113,"text":26438},{"id":4578,"depth":106,"text":4579,"children":31297},[31298,31299],{"id":26611,"depth":113,"text":26612},{"id":26861,"depth":113,"text":26862},{"id":5124,"depth":106,"text":5125,"children":31301},[31302,31303,31304],{"id":27090,"depth":113,"text":27091},{"id":27264,"depth":113,"text":27265},{"id":27488,"depth":113,"text":27489},{"id":27776,"depth":106,"text":27777,"children":31306},[31307,31308,31309,31310,31311],{"id":27783,"depth":113,"text":27784},{"id":27952,"depth":113,"text":27953},{"id":28103,"depth":113,"text":28104},{"id":7412,"depth":113,"text":7413},{"id":28563,"depth":113,"text":28564},{"id":28596,"depth":106,"text":28597,"children":31313},[31314,31315,31316],{"id":28600,"depth":113,"text":28601},{"id":28740,"depth":113,"text":28741},{"id":28932,"depth":113,"text":28933},{"id":29124,"depth":106,"text":29125,"children":31318},[31319,31320,31321,31322],{"id":29134,"depth":113,"text":29135},{"id":29195,"depth":113,"text":29196},{"id":29417,"depth":113,"text":29417},{"id":29552,"depth":113,"text":29553},{"id":29796,"depth":106,"text":29797},{"id":9291,"depth":106,"text":9292,"children":31325},[31326,31327,31328,31329,31330],{"id":30146,"depth":113,"text":30147},{"id":30357,"depth":113,"text":30358},{"id":4051,"depth":113,"text":4052},{"id":30680,"depth":113,"text":30681},{"id":31023,"depth":113,"text":31024},{"id":31130,"depth":106,"text":31131},"Go (Golang) syntax recap for coding interviews and fast ramp-up: slices, goroutines, channels, interfaces, errors, and generics, with runnable examples.","go-syntax-recap.png",{},"/backend/go-syntax-recap",{"title":24213,"description":31332},"Backend/9.go-syntax-recap",[31339,31340,10976,10977,29125],"Go","Golang","za1Uaj2W3Cy67mr7ok6jvI2_dxcAhUGvC0U4dle36iU",{"id":31343,"title":31344,"author":6,"body":31345,"date":42061,"description":42062,"draft":10966,"extension":10967,"guide":10968,"image":42063,"meta":42064,"navigation":109,"path":42065,"seo":42066,"stem":42067,"tags":42068,"__hash__":42070},"blog/Backend/7.top-111-laravel-interview-questions.md","Top 111 Laravel Interview Questions and Answers",{"type":8,"value":31346,"toc":41886},[31347,31354,31363,31367,31371,31376,31379,31383,31389,31421,31424,31428,31431,31484,31490,31494,31503,31516,31520,31526,31533,31626,31641,31645,31651,31674,31683,31686,31708,31716,31720,31733,31740,31814,31820,31824,31841,31848,31871,31874,31881,31890,31903,31916,31932,31966,31970,31974,31984,32001,32005,32012,32105,32119,32127,32133,32136,32190,32193,32207,32210,32227,32241,32245,32249,32259,32342,32361,32365,32371,32473,32487,32491,32497,32504,32547,32566,32570,32576,32716,32731,32741,32744,32761,32765,32774,32781,32831,32834,32838,32844,32897,32900,32903,32907,32912,32919,32923,32930,32961,32964,32968,32975,32992,33060,33075,33081,33085,33088,33207,33225,33229,33242,33245,33249,33253,33262,33292,33319,33333,33337,33347,33429,33435,33439,33446,33508,33519,33523,33532,33664,33667,33713,33716,33729,33732,33767,33789,33793,33796,33866,33883,33891,33897,33902,33937,33944,33987,33990,33994,33998,34008,34021,34072,34075,34079,34082,34087,34126,34135,34182,34194,34198,34201,34293,34377,34380,34386,34390,34396,34454,34463,34528,34531,34543,34546,34580,34661,34665,34674,34691,34776,34787,34791,34797,34880,34902,34912,34929,34932,34955,35017,35023,35027,35036,35046,35126,35136,35140,35150,35160,35205,35226,35230,35249,35255,35304,35310,35326,35335,35387,35450,35460,35469,35472,35495,35551,35569,35582,35585,35615,35712,35722,35735,35738,35777,35852,35855,35859,35883,35893,35993,36007,36011,36030,36041,36159,36171,36175,36181,36189,36239,36261,36264,36268,36278,36281,36385,36388,36420,36427,36437,36440,36449,36480,36489,36533,36542,36546,36550,36556,36641,36648,36664,36667,36711,36725,36729,36739,36834,36851,36855,36865,36868,36904,36919,36923,36929,36936,37021,37024,37028,37032,37045,37054,37064,37067,37076,37090,37121,37130,37143,37146,37151,37217,37222,37271,37281,37285,37291,37346,37352,37387,37396,37403,37406,37415,37421,37426,37439,37442,37450,37516,37542,37545,37549,37553,37563,37576,37580,37583,37606,37609,37613,37627,37713,37716,37720,37734,37743,37747,37760,37775,37785,37875,37878,37882,37899,37922,37926,37935,38017,38027,38031,38048,38148,38166,38170,38181,38260,38266,38270,38274,38294,38367,38370,38374,38377,38394,38408,38418,38422,38428,38434,38440,38444,38457,38551,38562,38572,38575,38587,38596,38608,38612,38627,38648,38666,38673,38682,38689,38710,38714,38717,38727,38782,38788,38865,38875,38879,38885,38892,38944,38955,38959,38963,38969,38987,39067,39075,39082,39087,39151,39162,39166,39171,39230,39269,39275,39299,39313,39317,39321,39331,39334,39397,39426,39443,39446,39481,39621,39635,39639,39652,39655,39750,39756,39760,39766,39769,39816,39826,39830,39834,39843,39920,39931,39935,39940,40074,40077,40081,40091,40130,40133,40213,40220,40224,40227,40230,40263,40269,40276,40290,40294,40309,40358,40361,40400,40403,40407,40411,40420,40499,40509,40513,40527,40642,40659,40663,40672,40803,40812,40816,40826,40859,40874,40878,40884,40895,40967,40974,40984,40994,41022,41025,41045,41057,41061,41065,41084,41191,41194,41198,41208,41214,41224,41288,41295,41306,41309,41318,41327,41364,41370,41383,41386,41416,41443,41452,41456,41460,41463,41473,41523,41530,41534,41552,41641,41647,41651,41657,41695,41702,41713,41722,41735,41748,41783,41786,41790,41793,41857,41860,41864,41880,41883],[11,31348,31349,31350,31353],{},"Laravel interviews are rarely about memorizing method names. They test whether you understand how the framework fits together: what happens between a request hitting ",[15,31351,31352],{},"public/index.php"," and a JSON response going back out, why Eloquent runs one extra query per row when you forget to eager load, how a queued job gets picked up by a worker running in a completely separate process. Once those mental models click, you can reason your way through a question you have never seen phrased quite that way before, even under interview pressure.",[11,31355,31356,31357,31359,31360,31362],{},"This article collects 111 of the most commonly asked Laravel interview questions, aimed at developers with zero to three years of experience. It stays deliberately Laravel-specific: you will not find generic backend theory (HTTP status codes, database normalization, caching strategy in the abstract) or questions about other frameworks here, since those get their own dedicated articles on this site; for that framework-agnostic side of a backend interview, the ",[23,31358,31],{"href":30}," article covers HTTP, databases, caching, and system design. If the PHP language itself feels rusty under the framework abstractions, the ",[23,31361,24230],{"href":15354}," refreshes the syntax and idioms Laravel is built on. What you will find is the stuff that shows up in almost every Laravel interview: the request lifecycle, the service container, routing, middleware, Eloquent, migrations, Blade, authentication, queues and jobs, events, testing, and the practical trade-offs behind them. Each answer starts with a clear definition, explains the reasoning, and includes a short example or code snippet only where it genuinely helps the idea stick.",[39,31364,31366],{"id":31365},"laravel-basics-and-architecture","Laravel Basics and Architecture",[242,31368,31370],{"id":31369},"_1-what-is-laravel-and-why-is-it-so-widely-used","1. What is Laravel, and why is it so widely used?",[11,31372,31373,31375],{},[10490,31374,15398],{}," is a free, open-source PHP web framework for building web applications and APIs. It gives you a well-organized starting point with batteries included: routing, an ORM (Eloquent), a templating engine (Blade), authentication, queues, caching, and testing tools, all wired together and ready to use.",[11,31377,31378],{},"The reason it became so popular is developer experience. Common tasks that take a lot of boilerplate in plain PHP (database access, form validation, sending mail, background jobs) are reduced to a few expressive lines. It also has excellent documentation, a huge ecosystem of first-party packages (Sanctum, Horizon, Nova, Telescope), and a large community, which means most problems you hit already have a well-known solution.",[242,31380,31382],{"id":31381},"_2-how-does-laravel-implement-the-mvc-pattern","2. How does Laravel implement the MVC pattern?",[11,31384,31385,31388],{},[10490,31386,31387],{},"MVC"," stands for Model, View, Controller, a way of separating an application into three responsibilities. In Laravel:",[11016,31390,31391,31401,31411],{},[11019,31392,1792,31393,31396,31397,31400],{},[10490,31394,31395],{},"Model"," (an Eloquent class in ",[15,31398,31399],{},"app/Models",") represents your data and the business rules around it, and talks to the database.",[11019,31402,1792,31403,31406,31407,31410],{},[10490,31404,31405],{},"View"," (a Blade template in ",[15,31408,31409],{},"resources/views",") is what the user sees, the HTML.",[11019,31412,1792,31413,31416,31417,31420],{},[10490,31414,31415],{},"Controller"," (a class in ",[15,31418,31419],{},"app/Http/Controllers",") sits in the middle: it receives the request, asks the model for data, and hands that data to a view to render.",[11,31422,31423],{},"A route maps a URL to a controller method, the controller pulls data from a model, and returns a view. Keeping these separate means your data logic, request handling, and presentation don't get tangled together, which makes the code far easier to change later.",[242,31425,31427],{"id":31426},"_3-can-you-walk-through-the-laravel-request-lifecycle","3. Can you walk through the Laravel request lifecycle?",[11,31429,31430],{},"Every request follows the same path, and knowing it explains where things like middleware and service providers fit in.",[11074,31432,31433,31439,31446,31461,31468,31478],{},[11019,31434,31435,31436,31438],{},"The web server sends every request to ",[15,31437,31352],{},", the single entry point.",[11019,31440,31441,31442,31445],{},"That file loads Composer's autoloader and bootstraps the framework from ",[15,31443,31444],{},"bootstrap/app.php",", creating the application instance (the service container).",[11019,31447,31448,31449,31452,31453,31456,31457,31460],{},"The request is sent into the ",[10490,31450,31451],{},"HTTP kernel",", which loads the configured ",[10490,31454,31455],{},"service providers",". This ",[15,31458,31459],{},"boot"," phase registers routes, database connections, and everything the app needs.",[11019,31462,31463,31464,31467],{},"The request passes through ",[10490,31465,31466],{},"global middleware"," (things like maintenance-mode checks and CSRF verification).",[11019,31469,1792,31470,31473,31474,31477],{},[10490,31471,31472],{},"router"," matches the request to a route, runs that route's ",[10490,31475,31476],{},"middleware",", and dispatches to a controller (or closure).",[11019,31479,31480,31481,31483],{},"The controller returns a ",[10490,31482,11485],{},", which travels back out through the middleware and is sent to the browser.",[11,31485,31486],{},[3108,31487],{"alt":31488,"src":31489},"Laravel request lifecycle diagram","/post-images/top-111-laravel-interview-questions/laravel-request-lifecycle-diagram.png",[242,31491,31493],{"id":31492},"_4-what-is-the-service-container-ioc-container-in-laravel","4. What is the service container (IoC container) in Laravel?",[11,31495,1792,31496,31499,31500,31502],{},[10490,31497,31498],{},"service container"," is Laravel's tool for managing class dependencies and resolving objects for you. Instead of manually creating objects with ",[15,31501,3334],{}," everywhere, you ask the container for a class, and it figures out how to build it, including building anything that class itself depends on.",[11,31504,31505,31506,394,31509,31511,31512,31515],{},"For example, if a controller needs a ",[15,31507,31508],{},"PaymentGateway",[15,31510,31508],{}," needs an HTTP client, you don't wire all that up by hand. You type-hint what you need, and the container constructs the whole chain. This is the foundation that makes dependency injection, facades, and much of Laravel's flexibility work. It's often called the ",[10490,31513,31514],{},"IoC"," (Inversion of Control) container because the framework, not your code, controls how objects get created.",[242,31517,31519],{"id":31518},"_5-what-is-dependency-injection-and-how-does-laravel-use-it","5. What is dependency injection, and how does Laravel use it?",[11,31521,31522,31525],{},[10490,31523,31524],{},"Dependency injection"," means a class receives the objects it depends on from the outside, rather than creating them itself. This keeps classes loosely coupled and much easier to test, because you can swap a real dependency for a fake one.",[11,31527,31528,31529,31532],{},"Laravel does this automatically through the service container. The most common form is ",[10490,31530,31531],{},"constructor injection",": you type-hint a dependency, and the container provides it.",[83,31534,31536],{"className":85,"code":31535,"language":87,"meta":88,"style":88},"class OrderController extends Controller\n{\n    public function __construct(protected PaymentGateway $gateway) {}\n\n    public function store(Request $request)\n    {\n        $this->gateway->charge($request->amount);\n    }\n}\n",[15,31537,31538,31550,31554,31572,31576,31592,31596,31618,31622],{"__ignoreMap":88},[92,31539,31540,31542,31545,31547],{"class":94,"line":95},[92,31541,6122],{"class":98},[92,31543,31544],{"class":5161}," OrderController",[92,31546,7096],{"class":98},[92,31548,31549],{"class":5161}," Controller\n",[92,31551,31552],{"class":94,"line":106},[92,31553,11212],{"class":119},[92,31555,31556,31558,31560,31562,31564,31566,31569],{"class":94,"line":113},[92,31557,6132],{"class":98},[92,31559,5659],{"class":98},[92,31561,6163],{"class":102},[92,31563,120],{"class":119},[92,31565,6331],{"class":98},[92,31567,31568],{"class":102}," PaymentGateway",[92,31570,31571],{"class":119}," $gateway) {}\n",[92,31573,31574],{"class":94,"line":138},[92,31575,110],{"emptyLinePlaceholder":109},[92,31577,31578,31580,31582,31585,31587,31589],{"class":94,"line":143},[92,31579,6132],{"class":98},[92,31581,5659],{"class":98},[92,31583,31584],{"class":5161}," store",[92,31586,120],{"class":119},[92,31588,11537],{"class":102},[92,31590,31591],{"class":119}," $request)\n",[92,31593,31594],{"class":94,"line":149},[92,31595,11267],{"class":119},[92,31597,31598,31600,31602,31605,31607,31610,31613,31615],{"class":94,"line":155},[92,31599,6180],{"class":102},[92,31601,1996],{"class":98},[92,31603,31604],{"class":119},"gateway",[92,31606,1996],{"class":98},[92,31608,31609],{"class":5161},"charge",[92,31611,31612],{"class":119},"($request",[92,31614,1996],{"class":98},[92,31616,31617],{"class":119},"amount);\n",[92,31619,31620],{"class":94,"line":161},[92,31621,5104],{"class":119},[92,31623,31624],{"class":94,"line":166},[92,31625,4711],{"class":119},[11,31627,31628,31629,31632,31633,31636,31637,31640],{},"You never call ",[15,31630,31631],{},"new PaymentGateway()","; Laravel resolves it for you. You can also ",[10490,31634,31635],{},"method inject"," by type-hinting parameters directly on a controller method, which is how ",[15,31638,31639],{},"Request $request"," shows up everywhere.",[242,31642,31644],{"id":31643},"_6-what-are-service-providers-and-what-role-do-they-play","6. What are service providers, and what role do they play?",[11,31646,31647,31650],{},[10490,31648,31649],{},"Service providers"," are the central place where your application is bootstrapped, meaning where things get registered and configured before the app handles a request. Almost every core Laravel feature (database, queues, mail) is booted through a service provider.",[11,31652,31653,31654,834,31657,31660,31661,31663,31664,31666,31667,1357,31670,31673],{},"A provider is a class with two methods, ",[15,31655,31656],{},"register()",[15,31658,31659],{},"boot()",". In ",[15,31662,31656],{}," you bind things into the service container; in ",[15,31665,31659],{}," you do setup that may rely on other services already being registered (like defining routes, view composers, or event listeners). You register your own providers in ",[15,31668,31669],{},"bootstrap/providers.php",[15,31671,31672],{},"config/app.php"," in older versions). They are the glue that tells the container how to build the pieces of your app.",[242,31675,31677,31678,834,31680,31682],{"id":31676},"_7-what-is-the-difference-between-the-register-and-boot-methods-of-a-service-provider","7. What is the difference between the ",[15,31679,31656],{},[15,31681,31659],{}," methods of a service provider?",[11,31684,31685],{},"Both run at startup, but at different times and for different purposes.",[11016,31687,31688,31700],{},[11019,31689,31690,31692,31693,31696,31697,31699],{},[15,31691,31656],{}," runs ",[10490,31694,31695],{},"first",", and its only job is to bind things into the service container. You should ",[1511,31698,5608],{}," try to use other services here, because they may not be registered yet.",[11019,31701,31702,31692,31704,31707],{},[15,31703,31659],{},[10490,31705,31706],{},"after all providers have been registered",", so at this point every binding in the whole application is available. This is where you do work that depends on other services being ready, like registering event listeners, defining gates, or publishing config.",[11,31709,31710,31711,31713,31714,81],{},"A simple rule: put container bindings in ",[15,31712,31656],{},", and anything that uses those bindings in ",[15,31715,31659],{},[242,31717,31719],{"id":31718},"_8-what-are-facades-and-how-do-they-actually-work-under-the-hood","8. What are facades, and how do they actually work under the hood?",[11,31721,6686,31722,31725,31726,6339,31729,31732],{},[10490,31723,31724],{},"facade"," is a class that provides a simple, static-looking interface to an object stored in the service container. When you write ",[15,31727,31728],{},"Cache::get('key')",[15,31730,31731],{},"Route::get(...)",", you're using a facade.",[11,31734,31735,31736,31739],{},"The trick is that facades are not truly static. Under the hood, every facade extends a base ",[15,31737,31738],{},"Facade"," class and defines an accessor key. When you call a static method on it, Laravel intercepts the call, resolves the real underlying object from the container, and forwards your call to it.",[83,31741,31743],{"className":85,"code":31742,"language":87,"meta":88,"style":88},"// This facade call...\nCache::put('name', 'Kashyap', 60);\n\n// ...is roughly equivalent to:\napp('cache')->put('name', 'Kashyap', 60);\n",[15,31744,31745,31750,31775,31779,31784],{"__ignoreMap":88},[92,31746,31747],{"class":94,"line":95},[92,31748,31749],{"class":134},"// This facade call...\n",[92,31751,31752,31755,31757,31759,31761,31763,31765,31768,31770,31773],{"class":94,"line":106},[92,31753,31754],{"class":102},"Cache",[92,31756,6818],{"class":98},[92,31758,11579],{"class":5161},[92,31760,120],{"class":119},[92,31762,1016],{"class":171},[92,31764,195],{"class":119},[92,31766,31767],{"class":171},"'Kashyap'",[92,31769,195],{"class":119},[92,31771,31772],{"class":102},"60",[92,31774,6289],{"class":119},[92,31776,31777],{"class":94,"line":113},[92,31778,110],{"emptyLinePlaceholder":109},[92,31780,31781],{"class":94,"line":138},[92,31782,31783],{"class":134},"// ...is roughly equivalent to:\n",[92,31785,31786,31789,31791,31794,31796,31798,31800,31802,31804,31806,31808,31810,31812],{"class":94,"line":143},[92,31787,31788],{"class":5161},"app",[92,31790,120],{"class":119},[92,31792,31793],{"class":171},"'cache'",[92,31795,5182],{"class":119},[92,31797,1996],{"class":98},[92,31799,11579],{"class":5161},[92,31801,120],{"class":119},[92,31803,1016],{"class":171},[92,31805,195],{"class":119},[92,31807,31767],{"class":171},[92,31809,195],{"class":119},[92,31811,31772],{"class":102},[92,31813,6289],{"class":119},[11,31815,31816,31817,81],{},"So facades give you clean, readable syntax while still using the real, fully testable object behind the scenes. That's why you can even fake a facade in tests with something like ",[15,31818,31819],{},"Cache::fake()",[242,31821,31823],{"id":31822},"_9-what-are-contracts-in-laravel-and-how-do-they-relate-to-facades","9. What are contracts in Laravel, and how do they relate to facades?",[11,31825,31826,31829,31830,31833,31834,31837,31838,31840],{},[10490,31827,31828],{},"Contracts"," are a set of interfaces that define the core services Laravel provides, for example ",[15,31831,31832],{},"Illuminate\\Contracts\\Cache\\Repository"," for caching or ",[15,31835,31836],{},"Illuminate\\Contracts\\Mail\\Mailer"," for mail. They describe ",[1511,31839,7645],{}," a service does without tying you to a specific implementation.",[11,31842,31843,31844,31847],{},"The relationship to facades is that they are two ways to use the same underlying service. A facade (",[15,31845,31846],{},"Cache::get()",") uses a static-looking helper; a contract is injected as an interface through the constructor:",[83,31849,31851],{"className":85,"code":31850,"language":87,"meta":88,"style":88},"public function __construct(private \\Illuminate\\Contracts\\Cache\\Repository $cache) {}\n",[15,31852,31853],{"__ignoreMap":88},[92,31854,31855,31857,31859,31861,31863,31865,31868],{"class":94,"line":95},[92,31856,6327],{"class":98},[92,31858,5659],{"class":98},[92,31860,6163],{"class":102},[92,31862,120],{"class":119},[92,31864,6335],{"class":98},[92,31866,31867],{"class":102}," \\Illuminate\\Contracts\\Cache\\Repository",[92,31869,31870],{"class":119}," $cache) {}\n",[11,31872,31873],{},"Both end up talking to the same cache service. Contracts are often preferred in larger applications or packages because depending on an interface makes your code more explicit about its dependencies and easier to mock in tests.",[242,31875,31877,31878,31880],{"id":31876},"_10-how-does-laravel-handle-environment-configuration-with-the-env-file","10. How does Laravel handle environment configuration with the ",[15,31879,13905],{}," file?",[11,31882,1792,31883,31885,31886,31889],{},[15,31884,13905],{}," file holds environment-specific settings (database credentials, API keys, the app URL) that differ between your local machine, staging, and production. It's kept out of version control so secrets don't end up in your repository, and ",[15,31887,31888],{},".env.example"," is committed as a template.",[11,31891,31892,31893,31896,31897,31899,31900,31902],{},"Laravel loads these values at startup, and you access them through configuration files in the ",[15,31894,31895],{},"config/"," directory, which read from the environment using the ",[15,31898,13914],{}," helper. This separation means you can deploy the exact same code to different servers, and each behaves correctly just by having a different ",[15,31901,13905],{}," file. Sensitive values never get hard-coded into the application.",[242,31904,31906,31907,834,31909,31912,31913,31915],{"id":31905},"_11-what-is-the-difference-between-env-and-config-and-why-should-you-not-call-env-outside-config-files","11. What is the difference between ",[15,31908,13914],{},[15,31910,31911],{},"config()",", and why should you not call ",[15,31914,13914],{}," outside config files?",[11,31917,31918,31920,31921,31923,31924,31926,31927,31929,31930,81],{},[15,31919,13914],{}," reads a raw value directly from the ",[15,31922,13905],{}," file (or the server environment). ",[15,31925,31911],{}," reads from the cached configuration files in ",[15,31928,31895],{},", which themselves were populated using ",[15,31931,13914],{},[11,31933,31934,31935,31938,31939,31945,31946,31948,31949,31952,31953,31955,31956,31958,31959,31961,31962,31965],{},"The important gotcha: once you run ",[15,31936,31937],{},"php artisan config:cache"," in production (which you should, for performance), Laravel loads all config from a single cached file and ",[10490,31940,31941,31942,31944],{},"stops reading ",[15,31943,13905],{}," at runtime",". Any ",[15,31947,13914],{}," call made ",[1511,31950,31951],{},"outside"," the config files will then return ",[15,31954,390],{},". So the rule is: only use ",[15,31957,13914],{}," inside ",[15,31960,31895],{}," files, and everywhere else in your app use ",[15,31963,31964],{},"config('services.stripe.key')",". This keeps your app working correctly whether or not the config is cached.",[39,31967,31969],{"id":31968},"artisan-and-the-command-line","Artisan and the Command Line",[242,31971,31973],{"id":31972},"_12-what-is-artisan","12. What is Artisan?",[11,31975,31976,31979,31980,31983],{},[10490,31977,31978],{},"Artisan"," is Laravel's command-line interface, the ",[15,31981,31982],{},"php artisan"," tool you run in your terminal. It ships with dozens of helpful commands for common development tasks so you don't have to write repetitive code by hand.",[11,31985,31986,31987,195,31990,195,31993,31996,31997,32000],{},"You use it to generate boilerplate (",[15,31988,31989],{},"make:controller",[15,31991,31992],{},"make:model",[15,31994,31995],{},"make:migration","), run migrations, clear caches, start the dev server (",[15,31998,31999],{},"serve","), manage queues, and much more. You can also write your own custom commands. It's one of the biggest reasons Laravel feels fast to work with.",[242,32002,32004],{"id":32003},"_13-how-do-you-create-a-custom-artisan-command","13. How do you create a custom Artisan command?",[11,32006,32007,32008,32011],{},"You generate one with ",[15,32009,32010],{},"php artisan make:command",", then define its behavior. This is useful for tasks you run regularly, like sending a weekly report or cleaning up old records.",[83,32013,32015],{"className":85,"code":32014,"language":87,"meta":88,"style":88},"class SendReports extends Command\n{\n    protected $signature = 'reports:send {--month=}';\n    protected $description = 'Send monthly reports to users';\n\n    public function handle()\n    {\n        $this->info('Sending reports...');\n        // your logic here\n    }\n}\n",[15,32016,32017,32028,32032,32045,32059,32063,32073,32077,32092,32097,32101],{"__ignoreMap":88},[92,32018,32019,32021,32024,32026],{"class":94,"line":95},[92,32020,6122],{"class":98},[92,32022,32023],{"class":5161}," SendReports",[92,32025,7096],{"class":98},[92,32027,11329],{"class":5161},[92,32029,32030],{"class":94,"line":106},[92,32031,11212],{"class":119},[92,32033,32034,32036,32038,32040,32043],{"class":94,"line":113},[92,32035,11338],{"class":98},[92,32037,11341],{"class":119},[92,32039,126],{"class":98},[92,32041,32042],{"class":171}," 'reports:send {--month=}'",[92,32044,229],{"class":119},[92,32046,32047,32049,32052,32054,32057],{"class":94,"line":138},[92,32048,11338],{"class":98},[92,32050,32051],{"class":119}," $description ",[92,32053,126],{"class":98},[92,32055,32056],{"class":171}," 'Send monthly reports to users'",[92,32058,229],{"class":119},[92,32060,32061],{"class":94,"line":143},[92,32062,110],{"emptyLinePlaceholder":109},[92,32064,32065,32067,32069,32071],{"class":94,"line":149},[92,32066,6132],{"class":98},[92,32068,5659],{"class":98},[92,32070,11255],{"class":5161},[92,32072,27470],{"class":119},[92,32074,32075],{"class":94,"line":155},[92,32076,11267],{"class":119},[92,32078,32079,32081,32083,32085,32087,32090],{"class":94,"line":161},[92,32080,6180],{"class":102},[92,32082,1996],{"class":98},[92,32084,11277],{"class":5161},[92,32086,120],{"class":119},[92,32088,32089],{"class":171},"'Sending reports...'",[92,32091,6289],{"class":119},[92,32093,32094],{"class":94,"line":166},[92,32095,32096],{"class":134},"        // your logic here\n",[92,32098,32099],{"class":94,"line":187},[92,32100,5104],{"class":119},[92,32102,32103],{"class":94,"line":217},[92,32104,4711],{"class":119},[11,32106,1792,32107,32110,32111,32114,32115,32118],{},[15,32108,32109],{},"$signature"," defines the command name and any arguments or options, and ",[15,32112,32113],{},"handle()"," contains the logic. Once defined, you run it with ",[15,32116,32117],{},"php artisan reports:send",", and (importantly) you can also schedule it to run automatically.",[242,32120,32122,32123,32126],{"id":32121},"_14-what-does-php-artisan-tinker-do","14. What does ",[15,32124,32125],{},"php artisan tinker"," do?",[11,32128,32129,32132],{},[10490,32130,32131],{},"Tinker"," is an interactive REPL (a read-eval-print loop) that boots your full Laravel application and lets you run PHP code against it, live in the terminal. It's incredibly handy for quick experiments and debugging.",[11,32134,32135],{},"You can create records, query models, test a piece of logic, or inspect a relationship without writing a route or a test first:",[83,32137,32139],{"className":85,"code":32138,"language":87,"meta":88,"style":88},">>> User::count()\n=> 42\n>>> User::factory()->create(['name' => 'Test'])\n",[15,32140,32141,32154,32160],{"__ignoreMap":88},[92,32142,32143,32146,32148,32150,32152],{"class":94,"line":95},[92,32144,32145],{"class":98},">>>",[92,32147,8699],{"class":102},[92,32149,6818],{"class":98},[92,32151,3243],{"class":5161},[92,32153,27470],{"class":119},[92,32155,32156,32158],{"class":94,"line":106},[92,32157,4521],{"class":98},[92,32159,24663],{"class":102},[92,32161,32162,32164,32166,32168,32171,32173,32175,32178,32180,32182,32184,32187],{"class":94,"line":113},[92,32163,32145],{"class":98},[92,32165,8699],{"class":102},[92,32167,6818],{"class":98},[92,32169,32170],{"class":5161},"factory",[92,32172,6042],{"class":119},[92,32174,1996],{"class":98},[92,32176,32177],{"class":5161},"create",[92,32179,486],{"class":119},[92,32181,1016],{"class":171},[92,32183,1019],{"class":98},[92,32185,32186],{"class":171}," 'Test'",[92,32188,32189],{"class":119},"])\n",[11,32191,32192],{},"Because it loads the real app, everything (Eloquent, config, services) works exactly as it would in your code. It's often the fastest way to answer \"does this query return what I think it does?\"",[242,32194,32196,32197,195,32200,394,32203,32206],{"id":32195},"_15-what-do-the-optimization-commands-like-configcache-routecache-and-viewcache-do-and-when-should-you-run-them","15. What do the optimization commands like ",[15,32198,32199],{},"config:cache",[15,32201,32202],{},"route:cache",[15,32204,32205],{},"view:cache"," do, and when should you run them?",[11,32208,32209],{},"These commands pre-compile parts of your app into fast, cached files so Laravel does less work on each request.",[11016,32211,32212,32217,32222],{},[11019,32213,32214,32216],{},[15,32215,32199],{}," merges all config files into one cached file, so Laravel doesn't parse dozens of files per request.",[11019,32218,32219,32221],{},[15,32220,32202],{}," compiles all route definitions into a single fast-loading file.",[11019,32223,32224,32226],{},[15,32225,32205],{}," pre-compiles all Blade templates into plain PHP ahead of time.",[11,32228,32229,32230,32233,32234,32236,32237,32240],{},"You should run these ",[10490,32231,32232],{},"in production"," (usually as part of your deployment), where the code doesn't change between requests. You should ",[1511,32235,5608],{}," use them during local development, because you'd have to rebuild the cache every time you edit a file. If something behaves strangely after deploying, ",[15,32238,32239],{},"php artisan optimize:clear"," clears all of these at once.",[39,32242,32244],{"id":32243},"routing","Routing",[242,32246,32248],{"id":32247},"_16-how-do-you-define-routes-in-laravel-and-what-route-files-exist-by-default","16. How do you define routes in Laravel, and what route files exist by default?",[11,32250,32251,32254,32255,32258],{},[10490,32252,32253],{},"Routes"," map an incoming URL and HTTP method to the code that should handle it (a controller method or a closure). You define them in the ",[15,32256,32257],{},"routes/"," directory.",[83,32260,32262],{"className":85,"code":32261,"language":87,"meta":88,"style":88},"Route::get('/posts', [PostController::class, 'index']);\nRoute::post('/posts', [PostController::class, 'store']);\nRoute::get('/posts/{post}', [PostController::class, 'show']);\n",[15,32263,32264,32291,32316],{"__ignoreMap":88},[92,32265,32266,32268,32270,32272,32274,32277,32279,32282,32284,32286,32289],{"class":94,"line":95},[92,32267,11466],{"class":102},[92,32269,6818],{"class":98},[92,32271,8985],{"class":5161},[92,32273,120],{"class":119},[92,32275,32276],{"class":171},"'/posts'",[92,32278,2708],{"class":119},[92,32280,32281],{"class":102},"PostController",[92,32283,6985],{"class":98},[92,32285,195],{"class":119},[92,32287,32288],{"class":171},"'index'",[92,32290,11674],{"class":119},[92,32292,32293,32295,32297,32299,32301,32303,32305,32307,32309,32311,32314],{"class":94,"line":106},[92,32294,11466],{"class":102},[92,32296,6818],{"class":98},[92,32298,11637],{"class":5161},[92,32300,120],{"class":119},[92,32302,32276],{"class":171},[92,32304,2708],{"class":119},[92,32306,32281],{"class":102},[92,32308,6985],{"class":98},[92,32310,195],{"class":119},[92,32312,32313],{"class":171},"'store'",[92,32315,11674],{"class":119},[92,32317,32318,32320,32322,32324,32326,32329,32331,32333,32335,32337,32340],{"class":94,"line":113},[92,32319,11466],{"class":102},[92,32321,6818],{"class":98},[92,32323,8985],{"class":5161},[92,32325,120],{"class":119},[92,32327,32328],{"class":171},"'/posts/{post}'",[92,32330,2708],{"class":119},[92,32332,32281],{"class":102},[92,32334,6985],{"class":98},[92,32336,195],{"class":119},[92,32338,32339],{"class":171},"'show'",[92,32341,11674],{"class":119},[11,32343,32344,32345,32348,32349,32352,32353,32356,32357,32360],{},"By default there's ",[15,32346,32347],{},"routes/web.php"," for web pages (these get session state and CSRF protection) and, when you install API support, ",[15,32350,32351],{},"routes/api.php"," for stateless API endpoints (these are prefixed with ",[15,32354,32355],{},"/api"," and use token auth instead of sessions). There's also ",[15,32358,32359],{},"console.php"," for Artisan commands. Grouping routes by file keeps web and API concerns cleanly separated.",[242,32362,32364],{"id":32363},"_17-what-are-named-routes-and-why-are-they-useful","17. What are named routes, and why are they useful?",[11,32366,6686,32367,32370],{},[10490,32368,32369],{},"named route"," is a route you give a name to, so you can refer to it by that name instead of hard-coding its URL throughout your app.",[83,32372,32374],{"className":85,"code":32373,"language":87,"meta":88,"style":88},"Route::get('/users/{id}/profile', [UserController::class, 'show'])->name('profile');\n\n// Then generate the URL by name:\nroute('profile', ['id' => 1]); // /users/1/profile\nreturn redirect()->route('profile', ['id' => 1]);\n",[15,32375,32376,32414,32418,32423,32446],{"__ignoreMap":88},[92,32377,32378,32380,32382,32384,32386,32389,32391,32394,32396,32398,32400,32403,32405,32407,32409,32412],{"class":94,"line":95},[92,32379,11466],{"class":102},[92,32381,6818],{"class":98},[92,32383,8985],{"class":5161},[92,32385,120],{"class":119},[92,32387,32388],{"class":171},"'/users/{id}/profile'",[92,32390,2708],{"class":119},[92,32392,32393],{"class":102},"UserController",[92,32395,6985],{"class":98},[92,32397,195],{"class":119},[92,32399,32339],{"class":171},[92,32401,32402],{"class":119},"])",[92,32404,1996],{"class":98},[92,32406,5271],{"class":5161},[92,32408,120],{"class":119},[92,32410,32411],{"class":171},"'profile'",[92,32413,6289],{"class":119},[92,32415,32416],{"class":94,"line":106},[92,32417,110],{"emptyLinePlaceholder":109},[92,32419,32420],{"class":94,"line":113},[92,32421,32422],{"class":134},"// Then generate the URL by name:\n",[92,32424,32425,32428,32430,32432,32434,32437,32439,32441,32443],{"class":94,"line":138},[92,32426,32427],{"class":5161},"route",[92,32429,120],{"class":119},[92,32431,32411],{"class":171},[92,32433,2708],{"class":119},[92,32435,32436],{"class":171},"'id'",[92,32438,1019],{"class":98},[92,32440,1849],{"class":102},[92,32442,5900],{"class":119},[92,32444,32445],{"class":134},"// /users/1/profile\n",[92,32447,32448,32450,32453,32455,32457,32459,32461,32463,32465,32467,32469,32471],{"class":94,"line":143},[92,32449,27101],{"class":98},[92,32451,32452],{"class":5161}," redirect",[92,32454,6042],{"class":119},[92,32456,1996],{"class":98},[92,32458,32427],{"class":5161},[92,32460,120],{"class":119},[92,32462,32411],{"class":171},[92,32464,2708],{"class":119},[92,32466,32436],{"class":171},[92,32468,1019],{"class":98},[92,32470,1849],{"class":102},[92,32472,11674],{"class":119},[11,32474,32475,32476,1524,32479,32482,32483,32486],{},"The benefit is maintainability: if you later change the URL from ",[15,32477,32478],{},"/users/{id}/profile",[15,32480,32481],{},"/members/{id}",", you only change it in one place. Every ",[15,32484,32485],{},"route('profile')"," call keeps working, because it references the name, not the path.",[242,32488,32490],{"id":32489},"_18-what-is-route-model-binding-and-whats-the-difference-between-implicit-and-explicit-binding","18. What is route model binding, and what's the difference between implicit and explicit binding?",[11,32492,32493,32496],{},[10490,32494,32495],{},"Route model binding"," automatically injects a model instance into your route or controller based on a route parameter, so you don't have to manually look it up.",[11,32498,32499,32500,32503],{},"With ",[10490,32501,32502],{},"implicit binding",", you type-hint an Eloquent model and name the route parameter to match. Laravel fetches the matching record by primary key automatically (and returns a 404 if it doesn't exist):",[83,32505,32507],{"className":85,"code":32506,"language":87,"meta":88,"style":88},"Route::get('/posts/{post}', function (Post $post) {\n    return $post; // already fetched by id\n});\n",[15,32508,32509,32533,32543],{"__ignoreMap":88},[92,32510,32511,32513,32515,32517,32519,32521,32523,32525,32527,32530],{"class":94,"line":95},[92,32512,11466],{"class":102},[92,32514,6818],{"class":98},[92,32516,8985],{"class":5161},[92,32518,120],{"class":119},[92,32520,32328],{"class":171},[92,32522,195],{"class":119},[92,32524,3556],{"class":98},[92,32526,3559],{"class":119},[92,32528,32529],{"class":102},"Post",[92,32531,32532],{"class":119}," $post) {\n",[92,32534,32535,32537,32540],{"class":94,"line":106},[92,32536,5195],{"class":98},[92,32538,32539],{"class":119}," $post; ",[92,32541,32542],{"class":134},"// already fetched by id\n",[92,32544,32545],{"class":94,"line":113},[92,32546,11624],{"class":119},[11,32548,32499,32549,32552,32553,10566,32556,32558,32559,6339,32562,32565],{},[10490,32550,32551],{},"explicit binding",", you manually tell Laravel how to resolve a parameter (for example, to bind by ",[15,32554,32555],{},"slug",[15,32557,28803],{},", or apply custom query logic) in a service provider using ",[15,32560,32561],{},"Route::model()",[15,32563,32564],{},"Route::bind()",". Implicit binding covers the common case; explicit binding is for when you need custom resolution.",[242,32567,32569],{"id":32568},"_19-what-are-route-groups-and-what-can-you-share-across-them","19. What are route groups, and what can you share across them?",[11,32571,32572,32575],{},[10490,32573,32574],{},"Route groups"," let you apply shared attributes to a bunch of routes at once, so you don't repeat yourself. Common shared attributes are middleware, a URL prefix, a name prefix, and a controller.",[83,32577,32579],{"className":85,"code":32578,"language":87,"meta":88,"style":88},"Route::middleware(['auth'])\n    ->prefix('admin')\n    ->name('admin.')\n    ->group(function () {\n        Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');\n        Route::get('/users', [UserController::class, 'index'])->name('users');\n    });\n",[15,32580,32581,32596,32610,32623,32637,32675,32711],{"__ignoreMap":88},[92,32582,32583,32585,32587,32589,32591,32594],{"class":94,"line":95},[92,32584,11466],{"class":102},[92,32586,6818],{"class":98},[92,32588,31476],{"class":5161},[92,32590,486],{"class":119},[92,32592,32593],{"class":171},"'auth'",[92,32595,32189],{"class":119},[92,32597,32598,32601,32604,32606,32608],{"class":94,"line":106},[92,32599,32600],{"class":98},"    ->",[92,32602,32603],{"class":5161},"prefix",[92,32605,120],{"class":119},[92,32607,9353],{"class":171},[92,32609,24307],{"class":119},[92,32611,32612,32614,32616,32618,32621],{"class":94,"line":113},[92,32613,32600],{"class":98},[92,32615,5271],{"class":5161},[92,32617,120],{"class":119},[92,32619,32620],{"class":171},"'admin.'",[92,32622,24307],{"class":119},[92,32624,32625,32627,32630,32632,32634],{"class":94,"line":138},[92,32626,32600],{"class":98},[92,32628,32629],{"class":5161},"group",[92,32631,120],{"class":119},[92,32633,3556],{"class":98},[92,32635,32636],{"class":119}," () {\n",[92,32638,32639,32642,32644,32646,32648,32651,32653,32656,32658,32660,32662,32664,32666,32668,32670,32673],{"class":94,"line":143},[92,32640,32641],{"class":102},"        Route",[92,32643,6818],{"class":98},[92,32645,8985],{"class":5161},[92,32647,120],{"class":119},[92,32649,32650],{"class":171},"'/dashboard'",[92,32652,2708],{"class":119},[92,32654,32655],{"class":102},"DashboardController",[92,32657,6985],{"class":98},[92,32659,195],{"class":119},[92,32661,32288],{"class":171},[92,32663,32402],{"class":119},[92,32665,1996],{"class":98},[92,32667,5271],{"class":5161},[92,32669,120],{"class":119},[92,32671,32672],{"class":171},"'dashboard'",[92,32674,6289],{"class":119},[92,32676,32677,32679,32681,32683,32685,32688,32690,32692,32694,32696,32698,32700,32702,32704,32706,32709],{"class":94,"line":149},[92,32678,32641],{"class":102},[92,32680,6818],{"class":98},[92,32682,8985],{"class":5161},[92,32684,120],{"class":119},[92,32686,32687],{"class":171},"'/users'",[92,32689,2708],{"class":119},[92,32691,32393],{"class":102},[92,32693,6985],{"class":98},[92,32695,195],{"class":119},[92,32697,32288],{"class":171},[92,32699,32402],{"class":119},[92,32701,1996],{"class":98},[92,32703,5271],{"class":5161},[92,32705,120],{"class":119},[92,32707,32708],{"class":171},"'users'",[92,32710,6289],{"class":119},[92,32712,32713],{"class":94,"line":155},[92,32714,32715],{"class":119},"    });\n",[11,32717,32718,32719,32722,32723,32726,32727,32730],{},"Here every route inside the group requires authentication, sits under ",[15,32720,32721],{},"/admin",", and gets an ",[15,32724,32725],{},"admin."," name prefix (so the first becomes ",[15,32728,32729],{},"admin.dashboard","). Groups keep related routes consistent and make bulk changes trivial.",[242,32732,32734,32735,834,32737,32740],{"id":32733},"_20-what-is-the-difference-between-the-web-and-api-middleware-groups","20. What is the difference between the ",[15,32736,12369],{},[15,32738,32739],{},"api"," middleware groups?",[11,32742,32743],{},"They are two sets of middleware applied to different kinds of routes, defined so web and API requests get the right defaults.",[11,32745,1792,32746,32748,32749,32751,32752,32748,32754,32756,32757,32760],{},[15,32747,12369],{}," group (applied to ",[15,32750,32347],{},") includes things like session handling, cookies, and CSRF protection, because browser-based pages need state and form security. The ",[15,32753,32739],{},[15,32755,32351],{},") is ",[10490,32758,32759],{},"stateless",": no sessions, no CSRF, and it typically applies rate limiting and expects token-based authentication instead. The distinction matters because an API consumed by mobile apps or JavaScript clients shouldn't rely on cookies and sessions the way a traditional web page does.",[242,32762,32764],{"id":32763},"_21-what-is-csrf-protection-and-how-does-laravel-apply-it","21. What is CSRF protection, and how does Laravel apply it?",[11,32766,32767,32770,32771,32773],{},[10490,32768,32769],{},"CSRF"," (Cross-Site Request Forgery) is an attack where a malicious site tricks a logged-in user's browser into submitting a request to your app without their intent. Laravel protects against it by requiring a secret token on every state-changing request (POST, PUT, PATCH, DELETE) made through the ",[15,32772,12369],{}," routes.",[11,32775,32776,32777,32780],{},"When you build a form in Blade, you include the token with the ",[15,32778,32779],{},"@csrf"," directive:",[83,32782,32786],{"className":32783,"code":32784,"language":32785,"meta":88,"style":88},"language-blade shiki shiki-themes github-dark","\u003Cform method=\"POST\" action=\"/profile\">\n    @csrf\n    \u003C!-- form fields -->\n\u003C/form>\n","blade",[15,32787,32788,32813,32818,32823],{"__ignoreMap":88},[92,32789,32790,32792,32795,32798,32800,32803,32806,32808,32811],{"class":94,"line":95},[92,32791,4671],{"class":119},[92,32793,32794],{"class":2145},"form",[92,32796,32797],{"class":5161}," method",[92,32799,126],{"class":119},[92,32801,32802],{"class":171},"\"POST\"",[92,32804,32805],{"class":5161}," action",[92,32807,126],{"class":119},[92,32809,32810],{"class":171},"\"/profile\"",[92,32812,2158],{"class":119},[92,32814,32815],{"class":94,"line":106},[92,32816,32817],{"class":98},"    @csrf\n",[92,32819,32820],{"class":94,"line":113},[92,32821,32822],{"class":134},"    \u003C!-- form fields -->\n",[92,32824,32825,32827,32829],{"class":94,"line":138},[92,32826,2153],{"class":119},[92,32828,32794],{"class":2145},[92,32830,2158],{"class":119},[11,32832,32833],{},"Laravel generates a token, stores it in the session, and the middleware verifies that the submitted token matches. A forged request from another site won't have the correct token, so it's rejected. API routes don't use CSRF because they rely on tokens instead of session cookies.",[242,32835,32837],{"id":32836},"_22-what-is-a-fallback-route","22. What is a fallback route?",[11,32839,6686,32840,32843],{},[10490,32841,32842],{},"fallback route"," defines what happens when no other route matches the incoming request. It's the last resort, and it lets you control the \"not found\" experience instead of showing the default 404 page.",[83,32845,32847],{"className":85,"code":32846,"language":87,"meta":88,"style":88},"Route::fallback(function () {\n    return response()->json(['message' => 'Not Found'], 404);\n});\n",[15,32848,32849,32864,32893],{"__ignoreMap":88},[92,32850,32851,32853,32855,32858,32860,32862],{"class":94,"line":95},[92,32852,11466],{"class":102},[92,32854,6818],{"class":98},[92,32856,32857],{"class":5161},"fallback",[92,32859,120],{"class":119},[92,32861,3556],{"class":98},[92,32863,32636],{"class":119},[92,32865,32866,32868,32870,32872,32874,32876,32878,32881,32883,32886,32888,32891],{"class":94,"line":106},[92,32867,5195],{"class":98},[92,32869,11604],{"class":5161},[92,32871,6042],{"class":119},[92,32873,1996],{"class":98},[92,32875,9672],{"class":5161},[92,32877,486],{"class":119},[92,32879,32880],{"class":171},"'message'",[92,32882,1019],{"class":98},[92,32884,32885],{"class":171}," 'Not Found'",[92,32887,3711],{"class":119},[92,32889,32890],{"class":102},"404",[92,32892,6289],{"class":119},[92,32894,32895],{"class":94,"line":113},[92,32896,11624],{"class":119},[11,32898,32899],{},"This is especially useful for APIs, where you'd rather return a clean JSON error than an HTML error page. It must be defined last, since Laravel evaluates it only after all other routes fail to match.",[39,32901,32902],{"id":31476},"Middleware",[242,32904,32906],{"id":32905},"_23-what-is-middleware-in-laravel","23. What is middleware in Laravel?",[11,32908,32909,32911],{},[10490,32910,32902],{}," is a layer of code that sits between the incoming request and your application logic, filtering or modifying requests as they pass through. Think of it as a series of checkpoints every request goes through before reaching the controller.",[11,32913,32914,32915,32918],{},"Common uses are authentication (is the user logged in?), CSRF verification, logging, rate limiting, and forcing HTTPS. For example, the built-in ",[15,32916,32917],{},"auth"," middleware checks whether a user is authenticated and redirects them to the login page if not. Middleware keeps this cross-cutting logic out of your controllers, so each controller can focus on its actual job.",[242,32920,32922],{"id":32921},"_24-what-is-the-difference-between-global-route-and-group-middleware","24. What is the difference between global, route, and group middleware?",[11,32924,32925,32926,32929],{},"They differ in ",[1511,32927,32928],{},"which"," requests they apply to.",[11016,32931,32932,32940,32950],{},[11019,32933,32934,32937,32938,81],{},[10490,32935,32936],{},"Global middleware"," runs on every single HTTP request into the app (for example, checking for maintenance mode). It's registered in ",[15,32939,31444],{},[11019,32941,32942,32945,32946,32949],{},[10490,32943,32944],{},"Route middleware"," is assigned to specific routes, so it only runs for those routes (for example, ",[15,32947,32948],{},"->middleware('auth')"," on a dashboard route).",[11019,32951,32952,32955,32956,834,32958,32960],{},[10490,32953,32954],{},"Group middleware"," is a named bundle of middleware (like the ",[15,32957,12369],{},[15,32959,32739],{}," groups) applied to a set of routes together.",[11,32962,32963],{},"The idea is to apply the right checks at the right scope: some things every request needs, others only certain routes need.",[242,32965,32967],{"id":32966},"_25-what-is-the-difference-between-before-and-after-middleware","25. What is the difference between \"before\" and \"after\" middleware?",[11,32969,32970,32971,32974],{},"The difference is ",[1511,32972,32973],{},"when"," the middleware does its work relative to the request reaching your application.",[11,32976,32977,32980,32981,32984,32985,32980,32988,32991],{},[10490,32978,32979],{},"Before middleware"," runs its logic ",[1511,32982,32983],{},"before"," the request is handled (for example, rejecting an unauthenticated user before the controller ever runs). ",[10490,32986,32987],{},"After middleware",[1511,32989,32990],{},"after"," the controller has produced a response, so it can inspect or modify that response (for example, adding a security header) on the way out.",[83,32993,32995],{"className":85,"code":32994,"language":87,"meta":88,"style":88},"public function handle($request, Closure $next)\n{\n    // \"before\" logic here (runs on the way in)\n\n    $response = $next($request);\n\n    // \"after\" logic here (runs on the way out)\n\n    return $response;\n}\n",[15,32996,32997,33013,33017,33022,33026,33036,33040,33045,33049,33056],{"__ignoreMap":88},[92,32998,32999,33001,33003,33005,33008,33010],{"class":94,"line":95},[92,33000,6327],{"class":98},[92,33002,5659],{"class":98},[92,33004,11255],{"class":5161},[92,33006,33007],{"class":119},"($request, ",[92,33009,5847],{"class":102},[92,33011,33012],{"class":119}," $next)\n",[92,33014,33015],{"class":94,"line":106},[92,33016,11212],{"class":119},[92,33018,33019],{"class":94,"line":113},[92,33020,33021],{"class":134},"    // \"before\" logic here (runs on the way in)\n",[92,33023,33024],{"class":94,"line":138},[92,33025,110],{"emptyLinePlaceholder":109},[92,33027,33028,33031,33033],{"class":94,"line":143},[92,33029,33030],{"class":119},"    $response ",[92,33032,126],{"class":98},[92,33034,33035],{"class":119}," $next($request);\n",[92,33037,33038],{"class":94,"line":149},[92,33039,110],{"emptyLinePlaceholder":109},[92,33041,33042],{"class":94,"line":155},[92,33043,33044],{"class":134},"    // \"after\" logic here (runs on the way out)\n",[92,33046,33047],{"class":94,"line":161},[92,33048,110],{"emptyLinePlaceholder":109},[92,33050,33051,33053],{"class":94,"line":166},[92,33052,5195],{"class":98},[92,33054,33055],{"class":119}," $response;\n",[92,33057,33058],{"class":94,"line":187},[92,33059,4711],{"class":119},[11,33061,33062,33063,33066,33067,33070,33071,33074],{},"Everything before ",[15,33064,33065],{},"$next($request)"," is \"before\" logic; everything after it is \"after\" logic. Because a request passes ",[1511,33068,33069],{},"into"," each layer and the response passes back ",[1511,33072,33073],{},"out",", middleware is often pictured as an onion.",[11,33076,33077],{},[3108,33078],{"alt":33079,"src":33080},"Middleware before and after pipeline onion diagram","/post-images/top-111-laravel-interview-questions/middleware-pipeline-diagram.png",[242,33082,33084],{"id":33083},"_26-how-do-you-pass-parameters-to-a-middleware","26. How do you pass parameters to a middleware?",[11,33086,33087],{},"You can pass extra arguments to middleware by appending them after a colon in the route definition, separated by commas. This is common for things like role checks.",[83,33089,33091],{"className":85,"code":33090,"language":87,"meta":88,"style":88},"// Route\nRoute::put('/post/{id}', ...)->middleware('role:editor');\n\n// Middleware handle signature\npublic function handle($request, Closure $next, $role)\n{\n    if (! $request->user()->hasRole($role)) {\n        abort(403);\n    }\n    return $next($request);\n}\n",[15,33092,33093,33098,33128,33132,33137,33152,33156,33181,33193,33197,33203],{"__ignoreMap":88},[92,33094,33095],{"class":94,"line":95},[92,33096,33097],{"class":134},"// Route\n",[92,33099,33100,33102,33104,33106,33108,33111,33113,33115,33117,33119,33121,33123,33126],{"class":94,"line":106},[92,33101,11466],{"class":102},[92,33103,6818],{"class":98},[92,33105,11579],{"class":5161},[92,33107,120],{"class":119},[92,33109,33110],{"class":171},"'/post/{id}'",[92,33112,195],{"class":119},[92,33114,5335],{"class":98},[92,33116,5182],{"class":119},[92,33118,1996],{"class":98},[92,33120,31476],{"class":5161},[92,33122,120],{"class":119},[92,33124,33125],{"class":171},"'role:editor'",[92,33127,6289],{"class":119},[92,33129,33130],{"class":94,"line":113},[92,33131,110],{"emptyLinePlaceholder":109},[92,33133,33134],{"class":94,"line":138},[92,33135,33136],{"class":134},"// Middleware handle signature\n",[92,33138,33139,33141,33143,33145,33147,33149],{"class":94,"line":143},[92,33140,6327],{"class":98},[92,33142,5659],{"class":98},[92,33144,11255],{"class":5161},[92,33146,33007],{"class":119},[92,33148,5847],{"class":102},[92,33150,33151],{"class":119}," $next, $role)\n",[92,33153,33154],{"class":94,"line":149},[92,33155,11212],{"class":119},[92,33157,33158,33160,33162,33164,33166,33168,33171,33173,33175,33178],{"class":94,"line":155},[92,33159,9161],{"class":98},[92,33161,3559],{"class":119},[92,33163,1501],{"class":98},[92,33165,11684],{"class":119},[92,33167,1996],{"class":98},[92,33169,33170],{"class":5161},"user",[92,33172,6042],{"class":119},[92,33174,1996],{"class":98},[92,33176,33177],{"class":5161},"hasRole",[92,33179,33180],{"class":119},"($role)) {\n",[92,33182,33183,33186,33188,33191],{"class":94,"line":161},[92,33184,33185],{"class":5161},"        abort",[92,33187,120],{"class":119},[92,33189,33190],{"class":102},"403",[92,33192,6289],{"class":119},[92,33194,33195],{"class":94,"line":166},[92,33196,5104],{"class":119},[92,33198,33199,33201],{"class":94,"line":187},[92,33200,5195],{"class":98},[92,33202,33035],{"class":119},[92,33204,33205],{"class":94,"line":217},[92,33206,4711],{"class":119},[11,33208,33209,33210,33213,33214,33217,33218,195,33221,33224],{},"Here ",[15,33211,33212],{},"editor"," is passed into the ",[15,33215,33216],{},"$role"," parameter. This lets one flexible middleware handle many cases (",[15,33219,33220],{},"role:admin",[15,33222,33223],{},"role:editor",") instead of writing a separate class for each.",[242,33226,33228],{"id":33227},"_27-what-is-terminable-middleware","27. What is terminable middleware?",[11,33230,33231,33234,33235,33237,33238,33241],{},[10490,33232,33233],{},"Terminable middleware"," is middleware that runs some logic ",[1511,33236,32990],{}," the response has already been sent to the browser. You define this by adding a ",[15,33239,33240],{},"terminate()"," method to the middleware class.",[11,33243,33244],{},"This is useful for slow, non-essential work you don't want to delay the response for, like writing detailed logs or updating session data. Because it happens after the user has already received their response, it doesn't affect how fast the page loads for them. Laravel's own session middleware uses this to save session data at the end of the request.",[39,33246,33248],{"id":33247},"controllers-requests-and-validation","Controllers, Requests, and Validation",[242,33250,33252],{"id":33251},"_28-what-are-controllers-and-what-is-a-resource-controller","28. What are controllers, and what is a resource controller?",[11,33254,6686,33255,33258,33259,33261],{},[10490,33256,33257],{},"controller"," groups related request-handling logic into a single class, instead of putting closures in your route file. For example, a ",[15,33260,32281],{}," might hold the logic for showing, creating, updating, and deleting posts.",[11,33263,6686,33264,33267,33268,33271,33272,195,33275,195,33277,195,33279,195,33282,195,33285,195,33288,33291],{},[10490,33265,33266],{},"resource controller"," is a shortcut for the standard set of CRUD actions. Running ",[15,33269,33270],{},"php artisan make:controller PostController --resource"," generates a controller with seven ready-made methods (",[15,33273,33274],{},"index",[15,33276,32177],{},[15,33278,11700],{},[15,33280,33281],{},"show",[15,33283,33284],{},"edit",[15,33286,33287],{},"update",[15,33289,33290],{},"destroy","), and a single route line wires them all up:",[83,33293,33295],{"className":85,"code":33294,"language":87,"meta":88,"style":88},"Route::resource('posts', PostController::class);\n",[15,33296,33297],{"__ignoreMap":88},[92,33298,33299,33301,33303,33306,33308,33311,33313,33315,33317],{"class":94,"line":95},[92,33300,11466],{"class":102},[92,33302,6818],{"class":98},[92,33304,33305],{"class":5161},"resource",[92,33307,120],{"class":119},[92,33309,33310],{"class":171},"'posts'",[92,33312,195],{"class":119},[92,33314,32281],{"class":102},[92,33316,6985],{"class":98},[92,33318,6289],{"class":119},[11,33320,33321,33322,33325,33326,33328,33329,33332],{},"This creates all the conventional routes (GET ",[15,33323,33324],{},"/posts",", POST ",[15,33327,33324],{},", GET ",[15,33330,33331],{},"/posts/{post}",", and so on) at once, keeping your routes consistent and concise.",[242,33334,33336],{"id":33335},"_29-what-is-a-single-action-invokable-controller","29. What is a single-action (invokable) controller?",[11,33338,6686,33339,33342,33343,33346],{},[10490,33340,33341],{},"single-action controller"," is a controller that handles just one action, using the magic ",[15,33344,33345],{},"__invoke()"," method instead of a named method. It's ideal when an action is complex enough to deserve its own class but doesn't fit into a resourceful group.",[83,33348,33350],{"className":85,"code":33349,"language":87,"meta":88,"style":88},"class GenerateReport extends Controller\n{\n    public function __invoke(Request $request)\n    {\n        // build and return the report\n    }\n}\n\n// Route (no method name needed)\nRoute::get('/report', GenerateReport::class);\n",[15,33351,33352,33363,33367,33381,33385,33390,33394,33398,33402,33407],{"__ignoreMap":88},[92,33353,33354,33356,33359,33361],{"class":94,"line":95},[92,33355,6122],{"class":98},[92,33357,33358],{"class":5161}," GenerateReport",[92,33360,7096],{"class":98},[92,33362,31549],{"class":5161},[92,33364,33365],{"class":94,"line":106},[92,33366,11212],{"class":119},[92,33368,33369,33371,33373,33375,33377,33379],{"class":94,"line":113},[92,33370,6132],{"class":98},[92,33372,5659],{"class":98},[92,33374,8373],{"class":102},[92,33376,120],{"class":119},[92,33378,11537],{"class":102},[92,33380,31591],{"class":119},[92,33382,33383],{"class":94,"line":138},[92,33384,11267],{"class":119},[92,33386,33387],{"class":94,"line":143},[92,33388,33389],{"class":134},"        // build and return the report\n",[92,33391,33392],{"class":94,"line":149},[92,33393,5104],{"class":119},[92,33395,33396],{"class":94,"line":155},[92,33397,4711],{"class":119},[92,33399,33400],{"class":94,"line":161},[92,33401,110],{"emptyLinePlaceholder":109},[92,33403,33404],{"class":94,"line":166},[92,33405,33406],{"class":134},"// Route (no method name needed)\n",[92,33408,33409,33411,33413,33415,33417,33420,33422,33425,33427],{"class":94,"line":187},[92,33410,11466],{"class":102},[92,33412,6818],{"class":98},[92,33414,8985],{"class":5161},[92,33416,120],{"class":119},[92,33418,33419],{"class":171},"'/report'",[92,33421,195],{"class":119},[92,33423,33424],{"class":102},"GenerateReport",[92,33426,6985],{"class":98},[92,33428,6289],{"class":119},[11,33430,32007,33431,33434],{},[15,33432,33433],{},"make:controller ReportController --invokable",". It keeps each focused action neatly self-contained.",[242,33436,33438],{"id":33437},"_30-how-does-validation-work-in-laravel","30. How does validation work in Laravel?",[11,33440,33441,33442,33445],{},"Validation checks that incoming request data meets your rules before you use it. The simplest way is ",[15,33443,33444],{},"$request->validate()"," in a controller, passing an array of field rules.",[83,33447,33449],{"className":85,"code":33448,"language":87,"meta":88,"style":88},"$validated = $request->validate([\n    'title' => 'required|string|max:255',\n    'email' => 'required|email|unique:users,email',\n    'age'   => 'nullable|integer|min:18',\n]);\n",[15,33450,33451,33467,33479,33491,33504],{"__ignoreMap":88},[92,33452,33453,33456,33458,33460,33462,33464],{"class":94,"line":95},[92,33454,33455],{"class":119},"$validated ",[92,33457,126],{"class":98},[92,33459,11684],{"class":119},[92,33461,1996],{"class":98},[92,33463,11661],{"class":5161},[92,33465,33466],{"class":119},"([\n",[92,33468,33469,33472,33474,33477],{"class":94,"line":106},[92,33470,33471],{"class":171},"    'title'",[92,33473,1019],{"class":98},[92,33475,33476],{"class":171}," 'required|string|max:255'",[92,33478,4772],{"class":119},[92,33480,33481,33484,33486,33489],{"class":94,"line":113},[92,33482,33483],{"class":171},"    'email'",[92,33485,1019],{"class":98},[92,33487,33488],{"class":171}," 'required|email|unique:users,email'",[92,33490,4772],{"class":119},[92,33492,33493,33496,33499,33502],{"class":94,"line":138},[92,33494,33495],{"class":171},"    'age'",[92,33497,33498],{"class":98},"   =>",[92,33500,33501],{"class":171}," 'nullable|integer|min:18'",[92,33503,4772],{"class":119},[92,33505,33506],{"class":94,"line":143},[92,33507,11674],{"class":119},[11,33509,33510,33511,33514,33515,33518],{},"If validation passes, ",[15,33512,33513],{},"$validated"," contains only the validated data, ready to use. If it fails, Laravel automatically stops and redirects the user back with the error messages and their old input (or returns a ",[15,33516,33517],{},"422"," JSON response for API requests). This means you never have to manually write \"if invalid, send back errors\" logic; the framework handles it.",[242,33520,33522],{"id":33521},"_31-what-is-a-form-request-and-why-would-you-use-one","31. What is a Form Request, and why would you use one?",[11,33524,6686,33525,33528,33529,81],{},[10490,33526,33527],{},"Form Request"," is a custom request class that holds your validation rules (and authorization logic) outside the controller, keeping the controller clean. You generate one with ",[15,33530,33531],{},"php artisan make:request StorePostRequest",[83,33533,33535],{"className":85,"code":33534,"language":87,"meta":88,"style":88},"class StorePostRequest extends FormRequest\n{\n    public function authorize(): bool\n    {\n        return $this->user()->can('create', Post::class);\n    }\n\n    public function rules(): array\n    {\n        return ['title' => 'required|max:255', 'body' => 'required'];\n    }\n}\n",[15,33536,33537,33549,33553,33569,33573,33602,33606,33610,33626,33630,33656,33660],{"__ignoreMap":88},[92,33538,33539,33541,33544,33546],{"class":94,"line":95},[92,33540,6122],{"class":98},[92,33542,33543],{"class":5161}," StorePostRequest",[92,33545,7096],{"class":98},[92,33547,33548],{"class":5161}," FormRequest\n",[92,33550,33551],{"class":94,"line":106},[92,33552,11212],{"class":119},[92,33554,33555,33557,33559,33562,33564,33566],{"class":94,"line":113},[92,33556,6132],{"class":98},[92,33558,5659],{"class":98},[92,33560,33561],{"class":5161}," authorize",[92,33563,6042],{"class":119},[92,33565,5185],{"class":98},[92,33567,33568],{"class":98}," bool\n",[92,33570,33571],{"class":94,"line":138},[92,33572,11267],{"class":119},[92,33574,33575,33577,33579,33581,33583,33585,33587,33589,33591,33594,33596,33598,33600],{"class":94,"line":143},[92,33576,6236],{"class":98},[92,33578,6239],{"class":102},[92,33580,1996],{"class":98},[92,33582,33170],{"class":5161},[92,33584,6042],{"class":119},[92,33586,1996],{"class":98},[92,33588,14508],{"class":5161},[92,33590,120],{"class":119},[92,33592,33593],{"class":171},"'create'",[92,33595,195],{"class":119},[92,33597,32529],{"class":102},[92,33599,6985],{"class":98},[92,33601,6289],{"class":119},[92,33603,33604],{"class":94,"line":149},[92,33605,5104],{"class":119},[92,33607,33608],{"class":94,"line":155},[92,33609,110],{"emptyLinePlaceholder":109},[92,33611,33612,33614,33616,33619,33621,33623],{"class":94,"line":161},[92,33613,6132],{"class":98},[92,33615,5659],{"class":98},[92,33617,33618],{"class":5161}," rules",[92,33620,6042],{"class":119},[92,33622,5185],{"class":98},[92,33624,33625],{"class":98}," array\n",[92,33627,33628],{"class":94,"line":166},[92,33629,11267],{"class":119},[92,33631,33632,33634,33636,33639,33641,33644,33646,33649,33651,33654],{"class":94,"line":187},[92,33633,6236],{"class":98},[92,33635,347],{"class":119},[92,33637,33638],{"class":171},"'title'",[92,33640,1019],{"class":98},[92,33642,33643],{"class":171}," 'required|max:255'",[92,33645,195],{"class":119},[92,33647,33648],{"class":171},"'body'",[92,33650,1019],{"class":98},[92,33652,33653],{"class":171}," 'required'",[92,33655,1034],{"class":119},[92,33657,33658],{"class":94,"line":217},[92,33659,5104],{"class":119},[92,33661,33662],{"class":94,"line":712},[92,33663,4711],{"class":119},[11,33665,33666],{},"Then you just type-hint it in the controller, and validation runs automatically before the method body executes:",[83,33668,33670],{"className":85,"code":33669,"language":87,"meta":88,"style":88},"public function store(StorePostRequest $request)\n{\n    Post::create($request->validated());\n}\n",[15,33671,33672,33687,33691,33709],{"__ignoreMap":88},[92,33673,33674,33676,33678,33680,33682,33685],{"class":94,"line":95},[92,33675,6327],{"class":98},[92,33677,5659],{"class":98},[92,33679,31584],{"class":5161},[92,33681,120],{"class":119},[92,33683,33684],{"class":102},"StorePostRequest",[92,33686,31591],{"class":119},[92,33688,33689],{"class":94,"line":106},[92,33690,11212],{"class":119},[92,33692,33693,33696,33698,33700,33702,33704,33707],{"class":94,"line":113},[92,33694,33695],{"class":102},"    Post",[92,33697,6818],{"class":98},[92,33699,32177],{"class":5161},[92,33701,31612],{"class":119},[92,33703,1996],{"class":98},[92,33705,33706],{"class":5161},"validated",[92,33708,9268],{"class":119},[92,33710,33711],{"class":94,"line":138},[92,33712,4711],{"class":119},[11,33714,33715],{},"You'd use one when validation rules get long, or when you want to reuse them, or to keep authorization and validation together in one tidy place.",[242,33717,33719,33720,195,33723,394,33726,897],{"id":33718},"_32-what-is-the-difference-between-request-input-request-query-and-request-all","32. What is the difference between ",[15,33721,33722],{},"$request->input()",[15,33724,33725],{},"$request->query()",[15,33727,33728],{},"$request->all()",[11,33730,33731],{},"All three read data from the request, but from different places.",[11016,33733,33734,33746,33759],{},[11019,33735,33736,33739,33740,33742,33743,81],{},[15,33737,33738],{},"$request->input('name')"," gets a value from the request body ",[1511,33741,1508],{}," the query string (it checks both), and is the general-purpose way to read a single field. You can pass a default: ",[15,33744,33745],{},"$request->input('name', 'guest')",[11019,33747,33748,33751,33752,33755,33756,33758],{},[15,33749,33750],{},"$request->query('page')"," reads only from the ",[10490,33753,33754],{},"URL query string"," (the part after ",[15,33757,897],{},").",[11019,33760,33761,1369,33763,33766],{},[15,33762,33728],{},[10490,33764,33765],{},"all"," input as an array, combining body and query data.",[11,33768,33769,33770,33773,33774,33777,33778,33781,33782,6339,33785,33788],{},"In practice you use ",[15,33771,33772],{},"input()"," most of the time, ",[15,33775,33776],{},"query()"," when you specifically want a URL parameter, and ",[15,33779,33780],{},"all()"," when you want everything at once (though for mass assignment you'd usually prefer ",[15,33783,33784],{},"validated()",[15,33786,33787],{},"only()"," for safety).",[242,33790,33792],{"id":33791},"_33-how-do-you-handle-file-uploads-in-laravel","33. How do you handle file uploads in Laravel?",[11,33794,33795],{},"When a form submits a file, you access it through the request and store it using the filesystem. Laravel makes this a one-liner.",[83,33797,33799],{"className":85,"code":33798,"language":87,"meta":88,"style":88},"$request->validate(['avatar' => 'required|image|max:2048']);\n\n$path = $request->file('avatar')->store('avatars', 'public');\n// $path is something like \"avatars/abc123.jpg\"\n",[15,33800,33801,33822,33826,33861],{"__ignoreMap":88},[92,33802,33803,33806,33808,33810,33812,33815,33817,33820],{"class":94,"line":95},[92,33804,33805],{"class":119},"$request",[92,33807,1996],{"class":98},[92,33809,11661],{"class":5161},[92,33811,486],{"class":119},[92,33813,33814],{"class":171},"'avatar'",[92,33816,1019],{"class":98},[92,33818,33819],{"class":171}," 'required|image|max:2048'",[92,33821,11674],{"class":119},[92,33823,33824],{"class":94,"line":106},[92,33825,110],{"emptyLinePlaceholder":109},[92,33827,33828,33831,33833,33835,33837,33839,33841,33843,33845,33847,33849,33851,33854,33856,33859],{"class":94,"line":113},[92,33829,33830],{"class":119},"$path ",[92,33832,126],{"class":98},[92,33834,11684],{"class":119},[92,33836,1996],{"class":98},[92,33838,11689],{"class":5161},[92,33840,120],{"class":119},[92,33842,33814],{"class":171},[92,33844,5182],{"class":119},[92,33846,1996],{"class":98},[92,33848,11700],{"class":5161},[92,33850,120],{"class":119},[92,33852,33853],{"class":171},"'avatars'",[92,33855,195],{"class":119},[92,33857,33858],{"class":171},"'public'",[92,33860,6289],{"class":119},[92,33862,33863],{"class":94,"line":138},[92,33864,33865],{"class":134},"// $path is something like \"avatars/abc123.jpg\"\n",[11,33867,33868,33871,33872,33875,33876,33878,33879,33882],{},[15,33869,33870],{},"$request->file('avatar')"," gets the uploaded file, and ",[15,33873,33874],{},"store()"," saves it to a disk (here the ",[15,33877,6327],{}," disk) with an automatically generated unique name, returning the path you can save to your database. You can also use ",[15,33880,33881],{},"storeAs()"," to control the filename. Behind the scenes this uses Laravel's storage abstraction, so switching from local disk to S3 later requires no code changes.",[242,33884,33886,33887,33890],{"id":33885},"_34-what-is-old-input-flashing-and-how-does-withinput-help","34. What is old input flashing, and how does ",[15,33888,33889],{},"->withInput()"," help?",[11,33892,33893,33896],{},[10490,33894,33895],{},"Old input flashing"," means temporarily storing the user's submitted form data in the session so you can re-populate the form after a failed submission, instead of making them retype everything.",[11,33898,33899,33900,5185],{},"When validation fails, Laravel does this automatically. If you redirect manually, you opt in with ",[15,33901,33889],{},[83,33903,33905],{"className":85,"code":33904,"language":87,"meta":88,"style":88},"return redirect()->back()->withInput()->withErrors($validator);\n",[15,33906,33907],{"__ignoreMap":88},[92,33908,33909,33911,33913,33915,33917,33920,33922,33924,33927,33929,33931,33934],{"class":94,"line":95},[92,33910,27101],{"class":98},[92,33912,32452],{"class":5161},[92,33914,6042],{"class":119},[92,33916,1996],{"class":98},[92,33918,33919],{"class":5161},"back",[92,33921,6042],{"class":119},[92,33923,1996],{"class":98},[92,33925,33926],{"class":5161},"withInput",[92,33928,6042],{"class":119},[92,33930,1996],{"class":98},[92,33932,33933],{"class":5161},"withErrors",[92,33935,33936],{"class":119},"($validator);\n",[11,33938,33939,33940,33943],{},"Then in Blade you retrieve a previous value with the ",[15,33941,33942],{},"old()"," helper:",[83,33945,33947],{"className":32783,"code":33946,"language":32785,"meta":88,"style":88},"\u003Cinput name=\"email\" value=\"{{ old('email') }}\">\n",[15,33948,33949],{"__ignoreMap":88},[92,33950,33951,33953,33956,33959,33961,33964,33967,33969,33971,33974,33977,33980,33983,33985],{"class":94,"line":95},[92,33952,4671],{"class":119},[92,33954,33955],{"class":2145},"input",[92,33957,33958],{"class":5161}," name",[92,33960,126],{"class":119},[92,33962,33963],{"class":171},"\"email\"",[92,33965,33966],{"class":5161}," value",[92,33968,126],{"class":119},[92,33970,178],{"class":171},[92,33972,33973],{"class":102},"{{",[92,33975,33976],{"class":5161}," old",[92,33978,33979],{"class":171},"('email') ",[92,33981,33982],{"class":102},"}}",[92,33984,178],{"class":171},[92,33986,2158],{"class":119},[11,33988,33989],{},"This is a small but important detail for good user experience: a form that clears itself on every error is frustrating, and old input prevents that.",[39,33991,33993],{"id":33992},"eloquent-orm","Eloquent ORM",[242,33995,33997],{"id":33996},"_35-what-is-eloquent-and-what-design-pattern-does-it-follow","35. What is Eloquent, and what design pattern does it follow?",[11,33999,34000,34003,34004,34007],{},[10490,34001,34002],{},"Eloquent"," is Laravel's ORM (Object-Relational Mapper). It lets you interact with your database using PHP objects and methods instead of writing raw SQL. Each database table has a corresponding ",[10490,34005,34006],{},"model"," class, and each row becomes an instance of that model.",[11,34009,34010,34011,34014,34015,34017,34018,34020],{},"It follows the ",[10490,34012,34013],{},"Active Record"," pattern, meaning the model is responsible both for representing a row of data and for the database operations on it (saving, updating, deleting). So a single ",[15,34016,2078],{}," object holds the data ",[1511,34019,1505],{}," knows how to persist itself:",[83,34022,34024],{"className":85,"code":34023,"language":87,"meta":88,"style":88},"$user = User::find(1);\n$user->name = 'New Name';\n$user->save();\n",[15,34025,34026,34045,34061],{"__ignoreMap":88},[92,34027,34028,34030,34032,34034,34036,34039,34041,34043],{"class":94,"line":95},[92,34029,1009],{"class":119},[92,34031,126],{"class":98},[92,34033,8699],{"class":102},[92,34035,6818],{"class":98},[92,34037,34038],{"class":5161},"find",[92,34040,120],{"class":119},[92,34042,68],{"class":102},[92,34044,6289],{"class":119},[92,34046,34047,34049,34051,34054,34056,34059],{"class":94,"line":106},[92,34048,2078],{"class":119},[92,34050,1996],{"class":98},[92,34052,34053],{"class":119},"name ",[92,34055,126],{"class":98},[92,34057,34058],{"class":171}," 'New Name'",[92,34060,229],{"class":119},[92,34062,34063,34065,34067,34070],{"class":94,"line":113},[92,34064,2078],{"class":119},[92,34066,1996],{"class":98},[92,34068,34069],{"class":5161},"save",[92,34071,7730],{"class":119},[11,34073,34074],{},"This makes database code read almost like plain English, which is a big part of Eloquent's appeal.",[242,34076,34078],{"id":34077},"_36-what-is-the-difference-between-eloquent-and-the-query-builder","36. What is the difference between Eloquent and the Query Builder?",[11,34080,34081],{},"Both let you query the database, but at different levels of abstraction.",[11,34083,34084,34086],{},[10490,34085,34002],{}," works with model objects and gives you relationships, accessors, events, and other high-level features. It returns model instances (or collections of them).",[83,34088,34090],{"className":85,"code":34089,"language":87,"meta":88,"style":88},"$users = User::where('active', true)->get(); // collection of User models\n",[15,34091,34092],{"__ignoreMap":88},[92,34093,34094,34097,34099,34101,34103,34106,34108,34111,34113,34115,34117,34119,34121,34123],{"class":94,"line":95},[92,34095,34096],{"class":119},"$users ",[92,34098,126],{"class":98},[92,34100,8699],{"class":102},[92,34102,6818],{"class":98},[92,34104,34105],{"class":5161},"where",[92,34107,120],{"class":119},[92,34109,34110],{"class":171},"'active'",[92,34112,195],{"class":119},[92,34114,474],{"class":102},[92,34116,5182],{"class":119},[92,34118,1996],{"class":98},[92,34120,8985],{"class":5161},[92,34122,27477],{"class":119},[92,34124,34125],{"class":134},"// collection of User models\n",[11,34127,1792,34128,34131,34132,34134],{},[10490,34129,34130],{},"Query Builder"," is a lower-level, fluent interface for building SQL queries. It returns plain ",[15,34133,9693],{}," objects or arrays, not models, and has no concept of relationships or model events.",[83,34136,34138],{"className":85,"code":34137,"language":87,"meta":88,"style":88},"$users = DB::table('users')->where('active', true)->get(); // generic objects\n",[15,34139,34140],{"__ignoreMap":88},[92,34141,34142,34144,34146,34149,34151,34153,34155,34157,34159,34161,34163,34165,34167,34169,34171,34173,34175,34177,34179],{"class":94,"line":95},[92,34143,34096],{"class":119},[92,34145,126],{"class":98},[92,34147,34148],{"class":102}," DB",[92,34150,6818],{"class":98},[92,34152,4068],{"class":5161},[92,34154,120],{"class":119},[92,34156,32708],{"class":171},[92,34158,5182],{"class":119},[92,34160,1996],{"class":98},[92,34162,34105],{"class":5161},[92,34164,120],{"class":119},[92,34166,34110],{"class":171},[92,34168,195],{"class":119},[92,34170,474],{"class":102},[92,34172,5182],{"class":119},[92,34174,1996],{"class":98},[92,34176,8985],{"class":5161},[92,34178,27477],{"class":119},[92,34180,34181],{"class":134},"// generic objects\n",[11,34183,34184,34185,34188,34189,34193],{},"Eloquent is actually built ",[1511,34186,34187],{},"on top of"," the Query Builder. You use Eloquent for most application code because of its convenience, and drop down to the Query Builder for performance-sensitive queries or complex reporting where you don't need model features. If the underlying SQL itself feels shaky (keys, joins, indexes, schema design), the ",[23,34190,34192],{"href":34191},"/post/sql-made-dead-simple-rdbms-guide","SQL Made Dead Simple"," guide covers the relational fundamentals both of these build on.",[242,34195,34197],{"id":34196},"_37-what-eloquent-relationships-does-laravel-support","37. What Eloquent relationships does Laravel support?",[11,34199,34200],{},"Eloquent lets you define how models relate to each other, so you can navigate related data as if it were object properties. The main types are:",[11016,34202,34203,34221,34237,34255,34272],{},[11019,34204,34205,3559,34208,4100,34211,34214,34215,34217,34218,81],{},[10490,34206,34207],{},"One to One",[15,34209,34210],{},"hasOne",[15,34212,34213],{},"belongsTo","): a ",[15,34216,27917],{}," has one ",[15,34219,34220],{},"Profile",[11019,34222,34223,3559,34226,4100,34229,34214,34231,34233,34234,28390],{},[10490,34224,34225],{},"One to Many",[15,34227,34228],{},"hasMany",[15,34230,34213],{},[15,34232,32529],{}," has many ",[15,34235,34236],{},"Comment",[11019,34238,34239,3559,34242,34214,34245,34233,34247,34250,34251,34254],{},[10490,34240,34241],{},"Many to Many",[15,34243,34244],{},"belongsToMany",[15,34246,27917],{},[15,34248,34249],{},"Role","s and a role has many users, joined through a ",[10490,34252,34253],{},"pivot"," table.",[11019,34256,34257,3559,34260,34263,34264,34233,34267,34269,34270,81],{},[10490,34258,34259],{},"Has Many Through",[15,34261,34262],{},"hasManyThrough","): access distant relations, like a ",[15,34265,34266],{},"Country",[15,34268,32529],{},"s through ",[15,34271,27917],{},[11019,34273,34274,3559,34277,4100,34280,34214,34283,34285,34286,34288,34289,34292],{},[10490,34275,34276],{},"Polymorphic",[15,34278,34279],{},"morphTo",[15,34281,34282],{},"morphMany",[15,34284,34236],{}," can belong to either a ",[15,34287,32529],{}," or a ",[15,34290,34291],{},"Video"," through one relationship.",[83,34294,34296],{"className":85,"code":34295,"language":87,"meta":88,"style":88},"class Post extends Model\n{\n    public function comments()\n    {\n        return $this->hasMany(Comment::class);\n    }\n}\n\n// Usage\n$post->comments; // collection of related comments\n",[15,34297,34298,34310,34314,34325,34329,34347,34351,34355,34359,34364],{"__ignoreMap":88},[92,34299,34300,34302,34305,34307],{"class":94,"line":95},[92,34301,6122],{"class":98},[92,34303,34304],{"class":5161}," Post",[92,34306,7096],{"class":98},[92,34308,34309],{"class":5161}," Model\n",[92,34311,34312],{"class":94,"line":106},[92,34313,11212],{"class":119},[92,34315,34316,34318,34320,34323],{"class":94,"line":113},[92,34317,6132],{"class":98},[92,34319,5659],{"class":98},[92,34321,34322],{"class":5161}," comments",[92,34324,27470],{"class":119},[92,34326,34327],{"class":94,"line":138},[92,34328,11267],{"class":119},[92,34330,34331,34333,34335,34337,34339,34341,34343,34345],{"class":94,"line":143},[92,34332,6236],{"class":98},[92,34334,6239],{"class":102},[92,34336,1996],{"class":98},[92,34338,34228],{"class":5161},[92,34340,120],{"class":119},[92,34342,34236],{"class":102},[92,34344,6985],{"class":98},[92,34346,6289],{"class":119},[92,34348,34349],{"class":94,"line":149},[92,34350,5104],{"class":119},[92,34352,34353],{"class":94,"line":155},[92,34354,4711],{"class":119},[92,34356,34357],{"class":94,"line":161},[92,34358,110],{"emptyLinePlaceholder":109},[92,34360,34361],{"class":94,"line":166},[92,34362,34363],{"class":134},"// Usage\n",[92,34365,34366,34369,34371,34374],{"class":94,"line":187},[92,34367,34368],{"class":119},"$post",[92,34370,1996],{"class":98},[92,34372,34373],{"class":119},"comments; ",[92,34375,34376],{"class":134},"// collection of related comments\n",[11,34378,34379],{},"Once defined, relationships also power eager loading and let you query related data expressively.",[11,34381,34382],{},[3108,34383],{"alt":34384,"src":34385},"Eloquent relationship types diagram","/post-images/top-111-laravel-interview-questions/eloquent-relationships-diagram.png",[242,34387,34389],{"id":34388},"_38-what-is-the-n1-query-problem-and-how-does-eager-loading-fix-it","38. What is the N+1 query problem, and how does eager loading fix it?",[11,34391,1792,34392,34395],{},[10490,34393,34394],{},"N+1 problem"," happens when you load a list of records and then access a relationship on each one inside a loop, causing one extra query per record. For 100 posts, that's 1 query for the posts plus 100 queries for their authors, so 101 queries total.",[83,34397,34399],{"className":85,"code":34398,"language":87,"meta":88,"style":88},"$posts = Post::all(); // 1 query\nforeach ($posts as $post) {\n    echo $post->author->name; // 1 query EACH time = N queries\n}\n",[15,34400,34401,34419,34430,34450],{"__ignoreMap":88},[92,34402,34403,34406,34408,34410,34412,34414,34416],{"class":94,"line":95},[92,34404,34405],{"class":119},"$posts ",[92,34407,126],{"class":98},[92,34409,34304],{"class":102},[92,34411,6818],{"class":98},[92,34413,33765],{"class":5161},[92,34415,27477],{"class":119},[92,34417,34418],{"class":134},"// 1 query\n",[92,34420,34421,34423,34426,34428],{"class":94,"line":106},[92,34422,4394],{"class":98},[92,34424,34425],{"class":119}," ($posts ",[92,34427,4497],{"class":98},[92,34429,32532],{"class":119},[92,34431,34432,34434,34437,34439,34442,34444,34447],{"class":94,"line":113},[92,34433,5314],{"class":102},[92,34435,34436],{"class":119}," $post",[92,34438,1996],{"class":98},[92,34440,34441],{"class":119},"author",[92,34443,1996],{"class":98},[92,34445,34446],{"class":119},"name; ",[92,34448,34449],{"class":134},"// 1 query EACH time = N queries\n",[92,34451,34452],{"class":94,"line":138},[92,34453,4711],{"class":119},[11,34455,34456,34459,34460,5185],{},[10490,34457,34458],{},"Eager loading"," fixes it by fetching the related data upfront in just one additional query, using ",[15,34461,34462],{},"with()",[83,34464,34466],{"className":85,"code":34465,"language":87,"meta":88,"style":88},"$posts = Post::with('author')->get(); // 2 queries total, no matter how many posts\nforeach ($posts as $post) {\n    echo $post->author->name; // no extra queries\n}\n",[15,34467,34468,34497,34507,34524],{"__ignoreMap":88},[92,34469,34470,34472,34474,34476,34478,34481,34483,34486,34488,34490,34492,34494],{"class":94,"line":95},[92,34471,34405],{"class":119},[92,34473,126],{"class":98},[92,34475,34304],{"class":102},[92,34477,6818],{"class":98},[92,34479,34480],{"class":5161},"with",[92,34482,120],{"class":119},[92,34484,34485],{"class":171},"'author'",[92,34487,5182],{"class":119},[92,34489,1996],{"class":98},[92,34491,8985],{"class":5161},[92,34493,27477],{"class":119},[92,34495,34496],{"class":134},"// 2 queries total, no matter how many posts\n",[92,34498,34499,34501,34503,34505],{"class":94,"line":106},[92,34500,4394],{"class":98},[92,34502,34425],{"class":119},[92,34504,4497],{"class":98},[92,34506,32532],{"class":119},[92,34508,34509,34511,34513,34515,34517,34519,34521],{"class":94,"line":113},[92,34510,5314],{"class":102},[92,34512,34436],{"class":119},[92,34514,1996],{"class":98},[92,34516,34441],{"class":119},[92,34518,1996],{"class":98},[92,34520,34446],{"class":119},[92,34522,34523],{"class":134},"// no extra queries\n",[92,34525,34526],{"class":94,"line":138},[92,34527,4711],{"class":119},[11,34529,34530],{},"This is one of the most common and important Eloquent performance issues, and interviewers love asking about it because it's so easy to trip over.",[242,34532,34534,34535,195,34537,394,34540,897],{"id":34533},"_39-what-is-the-difference-between-with-load-and-withcount","39. What is the difference between ",[15,34536,34462],{},[15,34538,34539],{},"load()",[15,34541,34542],{},"withCount()",[11,34544,34545],{},"All three deal with relationships, but they're used in different situations.",[11016,34547,34548,34556,34568],{},[11019,34549,34550,987,34552,34555],{},[15,34551,34462],{},[10490,34553,34554],{},"eager loading",": you load the relationship at the same time as the main query. Use it when you know upfront you'll need the relation.",[11019,34557,34558,987,34560,34563,34564,34567],{},[15,34559,34539],{},[10490,34561,34562],{},"lazy eager loading",": you load a relationship onto models you ",[1511,34565,34566],{},"already"," fetched. Use it when you have a model in hand and then decide you need its relation.",[11019,34569,34570,34572,34573,34575,34576,34579],{},[15,34571,34542],{}," loads just the ",[1511,34574,3243],{}," of a relationship, not the records themselves, into an attribute like ",[15,34577,34578],{},"comments_count",". Use it when you only need \"how many,\" not the actual related rows.",[83,34581,34583],{"className":85,"code":34582,"language":87,"meta":88,"style":88},"$posts = Post::with('comments')->get();     // load comments upfront\n$posts->load('author');                      // add author afterwards\n$posts = Post::withCount('comments')->get(); // gets $post->comments_count\n",[15,34584,34585,34613,34633],{"__ignoreMap":88},[92,34586,34587,34589,34591,34593,34595,34597,34599,34602,34604,34606,34608,34610],{"class":94,"line":95},[92,34588,34405],{"class":119},[92,34590,126],{"class":98},[92,34592,34304],{"class":102},[92,34594,6818],{"class":98},[92,34596,34480],{"class":5161},[92,34598,120],{"class":119},[92,34600,34601],{"class":171},"'comments'",[92,34603,5182],{"class":119},[92,34605,1996],{"class":98},[92,34607,8985],{"class":5161},[92,34609,10473],{"class":119},[92,34611,34612],{"class":134},"// load comments upfront\n",[92,34614,34615,34618,34620,34623,34625,34627,34630],{"class":94,"line":106},[92,34616,34617],{"class":119},"$posts",[92,34619,1996],{"class":98},[92,34621,34622],{"class":5161},"load",[92,34624,120],{"class":119},[92,34626,34485],{"class":171},[92,34628,34629],{"class":119},");                      ",[92,34631,34632],{"class":134},"// add author afterwards\n",[92,34634,34635,34637,34639,34641,34643,34646,34648,34650,34652,34654,34656,34658],{"class":94,"line":113},[92,34636,34405],{"class":119},[92,34638,126],{"class":98},[92,34640,34304],{"class":102},[92,34642,6818],{"class":98},[92,34644,34645],{"class":5161},"withCount",[92,34647,120],{"class":119},[92,34649,34601],{"class":171},[92,34651,5182],{"class":119},[92,34653,1996],{"class":98},[92,34655,8985],{"class":5161},[92,34657,27477],{"class":119},[92,34659,34660],{"class":134},"// gets $post->comments_count\n",[242,34662,34664],{"id":34663},"_40-what-are-accessors-and-mutators","40. What are accessors and mutators?",[11,34666,34667,834,34670,34673],{},[10490,34668,34669],{},"Accessors",[10490,34671,34672],{},"mutators"," let you transform an attribute's value when you read it or write it on a model, so the transformation logic lives in the model instead of being scattered around.",[11,34675,26615,34676,34679,34680,34682,34683,34686,34687,34690],{},[10490,34677,34678],{},"accessor"," formats a value when you ",[1511,34681,8985],{}," it; a ",[10490,34684,34685],{},"mutator"," formats it when you ",[1511,34688,34689],{},"set"," it. In modern Laravel both are defined together in one method:",[83,34692,34694],{"className":85,"code":34693,"language":87,"meta":88,"style":88},"protected function name(): Attribute\n{\n    return Attribute::make(\n        get: fn ($value) => ucfirst($value),        // accessor\n        set: fn ($value) => strtolower($value),     // mutator\n    );\n}\n",[15,34695,34696,34711,34715,34728,34748,34767,34772],{"__ignoreMap":88},[92,34697,34698,34700,34702,34704,34706,34708],{"class":94,"line":95},[92,34699,6331],{"class":98},[92,34701,5659],{"class":98},[92,34703,33958],{"class":5161},[92,34705,6042],{"class":119},[92,34707,5185],{"class":98},[92,34709,34710],{"class":102}," Attribute\n",[92,34712,34713],{"class":94,"line":106},[92,34714,11212],{"class":119},[92,34716,34717,34719,34722,34724,34726],{"class":94,"line":113},[92,34718,5195],{"class":98},[92,34720,34721],{"class":102}," Attribute",[92,34723,6818],{"class":98},[92,34725,26148],{"class":5161},[92,34727,6602],{"class":119},[92,34729,34730,34733,34735,34737,34740,34742,34745],{"class":94,"line":138},[92,34731,34732],{"class":5161},"        get",[92,34734,5263],{"class":119},[92,34736,3466],{"class":98},[92,34738,34739],{"class":119}," ($value) => ",[92,34741,2356],{"class":102},[92,34743,34744],{"class":119},"($value),        ",[92,34746,34747],{"class":134},"// accessor\n",[92,34749,34750,34753,34755,34757,34759,34761,34764],{"class":94,"line":143},[92,34751,34752],{"class":5161},"        set",[92,34754,5263],{"class":119},[92,34756,3466],{"class":98},[92,34758,34739],{"class":119},[92,34760,2341],{"class":102},[92,34762,34763],{"class":119},"($value),     ",[92,34765,34766],{"class":134},"// mutator\n",[92,34768,34769],{"class":94,"line":149},[92,34770,34771],{"class":119},"    );\n",[92,34773,34774],{"class":94,"line":155},[92,34775,4711],{"class":119},[11,34777,34778,34779,34782,34783,34786],{},"Now reading ",[15,34780,34781],{},"$user->name"," returns it capitalized, and setting it stores it lowercased. A classic use is hashing a password on set, or combining first and last name into a ",[15,34784,34785],{},"full_name"," on get.",[242,34788,34790],{"id":34789},"_41-what-are-attribute-casts-and-how-do-they-differ-from-accessors","41. What are attribute casts, and how do they differ from accessors?",[11,34792,34793,34796],{},[10490,34794,34795],{},"Casts"," automatically convert an attribute to a common data type when you read it from or write it to the database, using a simple declaration instead of custom logic. Databases store everything as strings or numbers, so casts save you from converting manually every time.",[83,34798,34800],{"className":85,"code":34799,"language":87,"meta":88,"style":88},"protected function casts(): array\n{\n    return [\n        'is_admin'   => 'boolean',\n        'options'    => 'array',      // JSON column \u003C-> PHP array\n        'published_at' => 'datetime', // string \u003C-> Carbon instance\n    ];\n}\n",[15,34801,34802,34817,34821,34827,34839,34856,34871,34876],{"__ignoreMap":88},[92,34803,34804,34806,34808,34811,34813,34815],{"class":94,"line":95},[92,34805,6331],{"class":98},[92,34807,5659],{"class":98},[92,34809,34810],{"class":5161}," casts",[92,34812,6042],{"class":119},[92,34814,5185],{"class":98},[92,34816,33625],{"class":98},[92,34818,34819],{"class":94,"line":106},[92,34820,11212],{"class":119},[92,34822,34823,34825],{"class":94,"line":113},[92,34824,5195],{"class":98},[92,34826,3034],{"class":119},[92,34828,34829,34832,34834,34837],{"class":94,"line":138},[92,34830,34831],{"class":171},"        'is_admin'",[92,34833,33498],{"class":98},[92,34835,34836],{"class":171}," 'boolean'",[92,34838,4772],{"class":119},[92,34840,34841,34844,34847,34850,34853],{"class":94,"line":143},[92,34842,34843],{"class":171},"        'options'",[92,34845,34846],{"class":98},"    =>",[92,34848,34849],{"class":171}," 'array'",[92,34851,34852],{"class":119},",      ",[92,34854,34855],{"class":134},"// JSON column \u003C-> PHP array\n",[92,34857,34858,34861,34863,34866,34868],{"class":94,"line":149},[92,34859,34860],{"class":171},"        'published_at'",[92,34862,1019],{"class":98},[92,34864,34865],{"class":171}," 'datetime'",[92,34867,195],{"class":119},[92,34869,34870],{"class":134},"// string \u003C-> Carbon instance\n",[92,34872,34873],{"class":94,"line":155},[92,34874,34875],{"class":119},"    ];\n",[92,34877,34878],{"class":94,"line":161},[92,34879,4711],{"class":119},[11,34881,14550,34882,34885,34886,529,34888,394,34890,34893,34894,34897,34898,34901],{},[15,34883,34884],{},"$user->is_admin"," is a real ",[15,34887,474],{},[15,34889,2300],{},[15,34891,34892],{},"$user->options"," is an array you can work with directly. The difference from an accessor is that casts are for ",[1511,34895,34896],{},"standard type conversions"," (boolean, array, date, decimal), declared in one line, whereas accessors are for ",[1511,34899,34900],{},"custom formatting logic"," you write yourself. Reach for a cast first; use an accessor when no built-in cast fits.",[242,34903,34905,34906,834,34909,897],{"id":34904},"_42-what-is-mass-assignment-and-whats-the-difference-between-fillable-and-guarded","42. What is mass assignment, and what's the difference between ",[15,34907,34908],{},"$fillable",[15,34910,34911],{},"$guarded",[11,34913,34914,34917,34918,34921,34922,34925,34926,81],{},[10490,34915,34916],{},"Mass assignment"," is creating or updating a model by passing an array of attributes at once, like ",[15,34919,34920],{},"User::create($request->all())",". It's convenient, but risky: if a user sneaks an unexpected field (like ",[15,34923,34924],{},"is_admin",") into the request, it could get written to the database. This is a ",[10490,34927,34928],{},"mass assignment vulnerability",[11,34930,34931],{},"Laravel protects against this by requiring you to declare which attributes are safe to mass assign, using one of two opposite properties:",[11016,34933,34934,34942],{},[11019,34935,34936,8939,34938,34941],{},[15,34937,34908],{},[10490,34939,34940],{},"allowlist",": only these attributes can be mass assigned.",[11019,34943,34944,34946,34947,34950,34951,34954],{},[15,34945,34911],{}," is a ",[10490,34948,34949],{},"blocklist",": everything ",[1511,34952,34953],{},"except"," these can be mass assigned.",[83,34956,34958],{"className":85,"code":34957,"language":87,"meta":88,"style":88},"protected $fillable = ['name', 'email', 'password']; // only these are allowed\n// OR\nprotected $guarded = ['id', 'is_admin']; // everything except these is allowed\n",[15,34959,34960,34989,34994],{"__ignoreMap":88},[92,34961,34962,34964,34967,34969,34971,34973,34975,34978,34980,34983,34986],{"class":94,"line":95},[92,34963,6331],{"class":98},[92,34965,34966],{"class":119}," $fillable ",[92,34968,126],{"class":98},[92,34970,347],{"class":119},[92,34972,1016],{"class":171},[92,34974,195],{"class":119},[92,34976,34977],{"class":171},"'email'",[92,34979,195],{"class":119},[92,34981,34982],{"class":171},"'password'",[92,34984,34985],{"class":119},"]; ",[92,34987,34988],{"class":134},"// only these are allowed\n",[92,34990,34991],{"class":94,"line":106},[92,34992,34993],{"class":134},"// OR\n",[92,34995,34996,34998,35001,35003,35005,35007,35009,35012,35014],{"class":94,"line":113},[92,34997,6331],{"class":98},[92,34999,35000],{"class":119}," $guarded ",[92,35002,126],{"class":98},[92,35004,347],{"class":119},[92,35006,32436],{"class":171},[92,35008,195],{"class":119},[92,35010,35011],{"class":171},"'is_admin'",[92,35013,34985],{"class":119},[92,35015,35016],{"class":134},"// everything except these is allowed\n",[11,35018,35019,35020,35022],{},"You use one or the other, not both. ",[15,35021,34908],{}," is generally considered safer because you explicitly list what's permitted rather than trying to remember everything to block.",[242,35024,35026],{"id":35025},"_43-what-are-query-scopes-local-and-global","43. What are query scopes (local and global)?",[11,35028,35029,35032,35033,35035],{},[10490,35030,35031],{},"Query scopes"," let you package common query constraints into reusable methods, so you don't repeat the same ",[15,35034,34105],{}," clauses everywhere.",[11,35037,6686,35038,35041,35042,35045],{},[10490,35039,35040],{},"local scope"," is a method you call explicitly. You define it with a ",[15,35043,35044],{},"scope"," prefix and call it without that prefix:",[83,35047,35049],{"className":85,"code":35048,"language":87,"meta":88,"style":88},"public function scopePublished($query)\n{\n    return $query->where('status', 'published');\n}\n\n// Usage\nPost::published()->latest()->get();\n",[15,35050,35051,35063,35067,35090,35094,35098,35102],{"__ignoreMap":88},[92,35052,35053,35055,35057,35060],{"class":94,"line":95},[92,35054,6327],{"class":98},[92,35056,5659],{"class":98},[92,35058,35059],{"class":5161}," scopePublished",[92,35061,35062],{"class":119},"($query)\n",[92,35064,35065],{"class":94,"line":106},[92,35066,11212],{"class":119},[92,35068,35069,35071,35074,35076,35078,35080,35083,35085,35088],{"class":94,"line":113},[92,35070,5195],{"class":98},[92,35072,35073],{"class":119}," $query",[92,35075,1996],{"class":98},[92,35077,34105],{"class":5161},[92,35079,120],{"class":119},[92,35081,35082],{"class":171},"'status'",[92,35084,195],{"class":119},[92,35086,35087],{"class":171},"'published'",[92,35089,6289],{"class":119},[92,35091,35092],{"class":94,"line":138},[92,35093,4711],{"class":119},[92,35095,35096],{"class":94,"line":143},[92,35097,110],{"emptyLinePlaceholder":109},[92,35099,35100],{"class":94,"line":149},[92,35101,34363],{"class":134},[92,35103,35104,35106,35108,35111,35113,35115,35118,35120,35122,35124],{"class":94,"line":155},[92,35105,32529],{"class":102},[92,35107,6818],{"class":98},[92,35109,35110],{"class":5161},"published",[92,35112,6042],{"class":119},[92,35114,1996],{"class":98},[92,35116,35117],{"class":5161},"latest",[92,35119,6042],{"class":119},[92,35121,1996],{"class":98},[92,35123,8985],{"class":5161},[92,35125,7730],{"class":119},[11,35127,6686,35128,35131,35132,35135],{},[10490,35129,35130],{},"global scope"," is applied automatically to ",[1511,35133,35134],{},"every"," query on a model until you explicitly remove it. A common use is a \"tenant\" scope that always filters records to the current user's organization, or soft deletes (which are implemented as a global scope). Local scopes keep your code DRY; global scopes enforce a constraint you never want to forget.",[242,35137,35139],{"id":35138},"_44-what-are-soft-deletes-and-how-do-they-work","44. What are soft deletes, and how do they work?",[11,35141,35142,35145,35146,35149],{},[10490,35143,35144],{},"Soft deletes"," let you \"delete\" a record without actually removing it from the database. Instead, Laravel sets a ",[15,35147,35148],{},"deleted_at"," timestamp, and the record is then automatically hidden from normal queries.",[11,35151,35152,35153,35156,35157,35159],{},"You enable it by adding the ",[15,35154,35155],{},"SoftDeletes"," trait to a model and a ",[15,35158,35148],{}," column to the table:",[83,35161,35163],{"className":85,"code":35162,"language":87,"meta":88,"style":88},"use Illuminate\\Database\\Eloquent\\SoftDeletes;\n\nclass Post extends Model\n{\n    use SoftDeletes;\n}\n",[15,35164,35165,35174,35178,35188,35192,35201],{"__ignoreMap":88},[92,35166,35167,35169,35172],{"class":94,"line":95},[92,35168,5612],{"class":98},[92,35170,35171],{"class":102}," Illuminate\\Database\\Eloquent\\SoftDeletes",[92,35173,229],{"class":119},[92,35175,35176],{"class":94,"line":106},[92,35177,110],{"emptyLinePlaceholder":109},[92,35179,35180,35182,35184,35186],{"class":94,"line":113},[92,35181,6122],{"class":98},[92,35183,34304],{"class":5161},[92,35185,7096],{"class":98},[92,35187,34309],{"class":5161},[92,35189,35190],{"class":94,"line":138},[92,35191,11212],{"class":119},[92,35193,35194,35196,35199],{"class":94,"line":143},[92,35195,7819],{"class":98},[92,35197,35198],{"class":102}," SoftDeletes",[92,35200,229],{"class":119},[92,35202,35203],{"class":94,"line":149},[92,35204,4711],{"class":119},[11,35206,14550,35207,35210,35211,35213,35214,35217,35218,35221,35222,35225],{},[15,35208,35209],{},"$post->delete()"," just stamps ",[15,35212,35148],{},", and the row is excluded from queries by default. You can still retrieve trashed records with ",[15,35215,35216],{},"withTrashed()",", restore them with ",[15,35219,35220],{},"restore()",", or permanently remove them with ",[15,35223,35224],{},"forceDelete()",". This is invaluable when you need an \"undo\" or an audit trail, like recovering an accidentally deleted account.",[242,35227,35229],{"id":35228},"_45-what-are-model-events-and-observers","45. What are model events and observers?",[11,35231,35232,35235,35236,195,35239,195,35242,195,35245,35248],{},[10490,35233,35234],{},"Model events"," are hooks that fire automatically at points in a model's lifecycle, such as ",[15,35237,35238],{},"creating",[15,35240,35241],{},"created",[15,35243,35244],{},"updating",[15,35246,35247],{},"deleted",", and so on. They let you run logic in response to database changes without cluttering your controllers.",[11,35250,26615,35251,35254],{},[10490,35252,35253],{},"observer"," is a dedicated class that groups all of a model's event handlers together, which is cleaner than defining them inline.",[83,35256,35258],{"className":85,"code":35257,"language":87,"meta":88,"style":88},"class UserObserver\n{\n    public function created(User $user)\n    {\n        // e.g. send a welcome email whenever a user is created\n    }\n}\n",[15,35259,35260,35267,35271,35287,35291,35296,35300],{"__ignoreMap":88},[92,35261,35262,35264],{"class":94,"line":95},[92,35263,6122],{"class":98},[92,35265,35266],{"class":5161}," UserObserver\n",[92,35268,35269],{"class":94,"line":106},[92,35270,11212],{"class":119},[92,35272,35273,35275,35277,35280,35282,35284],{"class":94,"line":113},[92,35274,6132],{"class":98},[92,35276,5659],{"class":98},[92,35278,35279],{"class":5161}," created",[92,35281,120],{"class":119},[92,35283,27917],{"class":102},[92,35285,35286],{"class":119}," $user)\n",[92,35288,35289],{"class":94,"line":138},[92,35290,11267],{"class":119},[92,35292,35293],{"class":94,"line":143},[92,35294,35295],{"class":134},"        // e.g. send a welcome email whenever a user is created\n",[92,35297,35298],{"class":94,"line":149},[92,35299,5104],{"class":119},[92,35301,35302],{"class":94,"line":155},[92,35303,4711],{"class":119},[11,35305,35306,35307,35309],{},"After registering the observer, its methods run automatically whenever the matching event occurs. This is perfect for side effects like sending notifications, logging changes, or setting a default value (for example, generating a slug in the ",[15,35308,35238],{}," event).",[242,35311,35313,35314,195,35317,195,35320,394,35323,897],{"id":35312},"_46-what-is-the-difference-between-find-first-firstorfail-and-findorfail","46. What is the difference between ",[15,35315,35316],{},"find()",[15,35318,35319],{},"first()",[15,35321,35322],{},"firstOrFail()",[15,35324,35325],{},"findOrFail()",[11,35327,35328,35329,35331,35332,35334],{},"They all retrieve a single record, but differ in ",[1511,35330,7649],{}," they find it and ",[1511,35333,7645],{}," they do when nothing matches.",[11016,35336,35337,35350,35362,35380],{},[11019,35338,35339,35342,35343,35346,35347,35349],{},[15,35340,35341],{},"find($id)"," looks up a record by its ",[10490,35344,35345],{},"primary key"," and returns ",[15,35348,390],{}," if not found.",[11019,35351,35352,35354,35355,35358,35359,35361],{},[15,35353,35319],{}," returns the ",[10490,35356,35357],{},"first record"," matching the current query constraints, or ",[15,35360,390],{}," if none match.",[11019,35363,35364,35367,35368,35370,35371,35377,35378,81],{},[15,35365,35366],{},"findOrFail($id)"," is like ",[15,35369,35316],{}," but ",[10490,35372,35373,35374],{},"throws a ",[15,35375,35376],{},"ModelNotFoundException"," (which Laravel turns into a 404 response) instead of returning ",[15,35379,390],{},[11019,35381,35382,35367,35384,35386],{},[15,35383,35322],{},[15,35385,35319],{}," but also throws a 404 when nothing matches.",[83,35388,35390],{"className":85,"code":35389,"language":87,"meta":88,"style":88},"User::find(1);                       // User or null\nUser::where('email', $e)->first();   // User or null\nUser::findOrFail(1);                 // User or 404\n",[15,35391,35392,35409,35432],{"__ignoreMap":88},[92,35393,35394,35396,35398,35400,35402,35404,35406],{"class":94,"line":95},[92,35395,27917],{"class":102},[92,35397,6818],{"class":98},[92,35399,34038],{"class":5161},[92,35401,120],{"class":119},[92,35403,68],{"class":102},[92,35405,3995],{"class":119},[92,35407,35408],{"class":134},"// User or null\n",[92,35410,35411,35413,35415,35417,35419,35421,35424,35426,35428,35430],{"class":94,"line":106},[92,35412,27917],{"class":102},[92,35414,6818],{"class":98},[92,35416,34105],{"class":5161},[92,35418,120],{"class":119},[92,35420,34977],{"class":171},[92,35422,35423],{"class":119},", $e)",[92,35425,1996],{"class":98},[92,35427,31695],{"class":5161},[92,35429,7178],{"class":119},[92,35431,35408],{"class":134},[92,35433,35434,35436,35438,35441,35443,35445,35447],{"class":94,"line":113},[92,35435,27917],{"class":102},[92,35437,6818],{"class":98},[92,35439,35440],{"class":5161},"findOrFail",[92,35442,120],{"class":119},[92,35444,68],{"class":102},[92,35446,2333],{"class":119},[92,35448,35449],{"class":134},"// User or 404\n",[11,35451,1792,35452,35455,35456,35459],{},[15,35453,35454],{},"OrFail"," variants are handy in controllers where a missing record should just return a 404 automatically, saving you a manual ",[15,35457,35458],{},"if (! $user) abort(404)"," check.",[242,35461,35463,35464,834,35467,897],{"id":35462},"_47-what-is-the-difference-between-get-and-all","47. What is the difference between ",[15,35465,35466],{},"get()",[15,35468,33780],{},[11,35470,35471],{},"Both return a collection of models, but they differ in whether you can constrain the query.",[11,35473,35474,35476,35477,35479,35480,35482,35483,35486,35487,195,35489,1375,35492,81],{},[15,35475,33780],{}," retrieves ",[10490,35478,35134],{}," row in the table with no conditions; it's a static shortcut. ",[15,35481,35466],{}," runs the query you've ",[1511,35484,35485],{},"built up"," with conditions like ",[15,35488,34105],{},[15,35490,35491],{},"orderBy",[15,35493,35494],{},"limit",[83,35496,35498],{"className":85,"code":35497,"language":87,"meta":88,"style":88},"User::all();                                  // every user\nUser::where('active', true)->orderBy('name')->get(); // filtered and sorted\n",[15,35499,35500,35514],{"__ignoreMap":88},[92,35501,35502,35504,35506,35508,35511],{"class":94,"line":95},[92,35503,27917],{"class":102},[92,35505,6818],{"class":98},[92,35507,33765],{"class":5161},[92,35509,35510],{"class":119},"();                                  ",[92,35512,35513],{"class":134},"// every user\n",[92,35515,35516,35518,35520,35522,35524,35526,35528,35530,35532,35534,35536,35538,35540,35542,35544,35546,35548],{"class":94,"line":106},[92,35517,27917],{"class":102},[92,35519,6818],{"class":98},[92,35521,34105],{"class":5161},[92,35523,120],{"class":119},[92,35525,34110],{"class":171},[92,35527,195],{"class":119},[92,35529,474],{"class":102},[92,35531,5182],{"class":119},[92,35533,1996],{"class":98},[92,35535,35491],{"class":5161},[92,35537,120],{"class":119},[92,35539,1016],{"class":171},[92,35541,5182],{"class":119},[92,35543,1996],{"class":98},[92,35545,8985],{"class":5161},[92,35547,27477],{"class":119},[92,35549,35550],{"class":134},"// filtered and sorted\n",[11,35552,35553,35554,35556,35557,35559,35560,35562,35563,35565,35566,35568],{},"So ",[15,35555,33780],{}," is fine for small tables you truly want in full, but for anything real you'll almost always use ",[15,35558,35466],{}," at the end of a query chain. A common beginner mistake is calling ",[15,35561,33780],{}," and then filtering in PHP, which pulls the whole table into memory; adding a ",[15,35564,34105],{}," and using ",[15,35567,35466],{}," lets the database do the filtering.",[242,35570,35572,35573,195,35576,394,35579,897],{"id":35571},"_48-what-is-the-difference-between-save-create-and-update","48. What is the difference between ",[15,35574,35575],{},"save()",[15,35577,35578],{},"create()",[15,35580,35581],{},"update()",[11,35583,35584],{},"These are three ways to write data with Eloquent.",[11016,35586,35587,35599,35610],{},[11019,35588,35589,35591,35592,35595,35596,35598],{},[15,35590,35575],{}," is called on a model ",[10490,35593,35594],{},"instance",". You set attributes, then call ",[15,35597,35575],{}," to persist them (it inserts a new row if the model is new, or updates it if it already exists).",[11019,35600,35601,35603,35604,35607,35608,33758],{},[15,35602,35578],{}," is a static method that ",[10490,35605,35606],{},"makes and saves a new record"," in one step from an array, and relies on mass assignment (",[15,35609,34908],{},[11019,35611,35612,35614],{},[15,35613,35581],{}," is called on an existing model (or a query) to change attributes and save in one step.",[83,35616,35618],{"className":85,"code":35617,"language":87,"meta":88,"style":88},"$user = new User;\n$user->name = 'Kashyap';\n$user->save();                       // insert\n\nUser::create(['name' => 'Kashyap']); // make + insert\n\n$user->update(['name' => 'New']);    // update existing\n",[15,35619,35620,35632,35647,35661,35665,35686,35690],{"__ignoreMap":88},[92,35621,35622,35624,35626,35628,35630],{"class":94,"line":95},[92,35623,1009],{"class":119},[92,35625,126],{"class":98},[92,35627,6274],{"class":98},[92,35629,8699],{"class":102},[92,35631,229],{"class":119},[92,35633,35634,35636,35638,35640,35642,35645],{"class":94,"line":106},[92,35635,2078],{"class":119},[92,35637,1996],{"class":98},[92,35639,34053],{"class":119},[92,35641,126],{"class":98},[92,35643,35644],{"class":171}," 'Kashyap'",[92,35646,229],{"class":119},[92,35648,35649,35651,35653,35655,35658],{"class":94,"line":113},[92,35650,2078],{"class":119},[92,35652,1996],{"class":98},[92,35654,34069],{"class":5161},[92,35656,35657],{"class":119},"();                       ",[92,35659,35660],{"class":134},"// insert\n",[92,35662,35663],{"class":94,"line":138},[92,35664,110],{"emptyLinePlaceholder":109},[92,35666,35667,35669,35671,35673,35675,35677,35679,35681,35683],{"class":94,"line":143},[92,35668,27917],{"class":102},[92,35670,6818],{"class":98},[92,35672,32177],{"class":5161},[92,35674,486],{"class":119},[92,35676,1016],{"class":171},[92,35678,1019],{"class":98},[92,35680,35644],{"class":171},[92,35682,5900],{"class":119},[92,35684,35685],{"class":134},"// make + insert\n",[92,35687,35688],{"class":94,"line":149},[92,35689,110],{"emptyLinePlaceholder":109},[92,35691,35692,35694,35696,35698,35700,35702,35704,35707,35709],{"class":94,"line":155},[92,35693,2078],{"class":119},[92,35695,1996],{"class":98},[92,35697,33287],{"class":5161},[92,35699,486],{"class":119},[92,35701,1016],{"class":171},[92,35703,1019],{"class":98},[92,35705,35706],{"class":171}," 'New'",[92,35708,495],{"class":119},[92,35710,35711],{"class":134},"// update existing\n",[11,35713,35714,834,35716,35718,35719,35721],{},[15,35715,35578],{},[15,35717,35581],{}," are the convenient array-based shortcuts; ",[15,35720,35575],{}," is the lower-level workhorse they build on.",[242,35723,35725,35726,195,35729,394,35732,32126],{"id":35724},"_49-what-do-firstorcreate-firstornew-and-updateorcreate-do","49. What do ",[15,35727,35728],{},"firstOrCreate()",[15,35730,35731],{},"firstOrNew()",[15,35733,35734],{},"updateOrCreate()",[11,35736,35737],{},"These are convenience methods for the common \"find it, or make it\" pattern, so you avoid writing a manual check-then-insert.",[11016,35739,35740,35750,35763],{},[11019,35741,35742,35745,35746,35749],{},[15,35743,35744],{},"firstOrCreate($attributes)"," finds the first record matching the attributes, or ",[10490,35747,35748],{},"creates and saves"," it if none exists.",[11019,35751,35752,35755,35756,35759,35760,35762],{},[15,35753,35754],{},"firstOrNew($attributes)"," is the same, but returns a ",[10490,35757,35758],{},"new unsaved"," instance if none exists (you call ",[15,35761,35575],{}," yourself later).",[11019,35764,35765,35768,35769,35772,35773,35776],{},[15,35766,35767],{},"updateOrCreate($search, $values)"," finds a matching record and ",[10490,35770,35771],{},"updates"," it, or ",[10490,35774,35775],{},"creates"," a new one if none is found.",[83,35778,35780],{"className":85,"code":35779,"language":87,"meta":88,"style":88},"// find a user by email, or create one\nUser::firstOrCreate(['email' => $email], ['name' => $name]);\n\n// update a setting if it exists, otherwise create it\nSetting::updateOrCreate(['key' => 'theme'], ['value' => 'dark']);\n",[15,35781,35782,35787,35812,35816,35821],{"__ignoreMap":88},[92,35783,35784],{"class":94,"line":95},[92,35785,35786],{"class":134},"// find a user by email, or create one\n",[92,35788,35789,35791,35793,35796,35798,35800,35802,35805,35807,35809],{"class":94,"line":106},[92,35790,27917],{"class":102},[92,35792,6818],{"class":98},[92,35794,35795],{"class":5161},"firstOrCreate",[92,35797,486],{"class":119},[92,35799,34977],{"class":171},[92,35801,1019],{"class":98},[92,35803,35804],{"class":119}," $email], [",[92,35806,1016],{"class":171},[92,35808,1019],{"class":98},[92,35810,35811],{"class":119}," $name]);\n",[92,35813,35814],{"class":94,"line":113},[92,35815,110],{"emptyLinePlaceholder":109},[92,35817,35818],{"class":94,"line":138},[92,35819,35820],{"class":134},"// update a setting if it exists, otherwise create it\n",[92,35822,35823,35826,35828,35831,35833,35835,35837,35840,35842,35845,35847,35850],{"class":94,"line":143},[92,35824,35825],{"class":102},"Setting",[92,35827,6818],{"class":98},[92,35829,35830],{"class":5161},"updateOrCreate",[92,35832,486],{"class":119},[92,35834,12952],{"class":171},[92,35836,1019],{"class":98},[92,35838,35839],{"class":171}," 'theme'",[92,35841,3614],{"class":119},[92,35843,35844],{"class":171},"'value'",[92,35846,1019],{"class":98},[92,35848,35849],{"class":171}," 'dark'",[92,35851,11674],{"class":119},[11,35853,35854],{},"These prevent duplicate rows and race-y \"check if exists first\" code, which is why they show up so often in real projects (importing data, syncing settings, upserting records).",[242,35856,35858],{"id":35857},"_50-what-is-a-pivot-table-and-how-do-you-access-extra-pivot-columns","50. What is a pivot table, and how do you access extra pivot columns?",[11,35860,6686,35861,35864,35865,834,35868,35871,35872,35875,35876,834,35879,35882],{},[10490,35862,35863],{},"pivot table"," is an intermediate table that connects two models in a many-to-many relationship. For a ",[15,35866,35867],{},"users",[15,35869,35870],{},"roles"," relationship, the pivot table ",[15,35873,35874],{},"role_user"," holds pairs of ",[15,35877,35878],{},"user_id",[15,35880,35881],{},"role_id"," linking them.",[11,35884,35885,35886,35889,35890,35892],{},"Sometimes the pivot needs extra data, like when a role was assigned. You declare those columns with ",[15,35887,35888],{},"withPivot()"," and then read them via the ",[15,35891,34253],{}," property:",[83,35894,35896],{"className":85,"code":35895,"language":87,"meta":88,"style":88},"public function roles()\n{\n    return $this->belongsToMany(Role::class)->withPivot('assigned_at');\n}\n\n// Access it:\nforeach ($user->roles as $role) {\n    echo $role->pivot->assigned_at;\n}\n",[15,35897,35898,35909,35913,35943,35947,35951,35956,35973,35989],{"__ignoreMap":88},[92,35899,35900,35902,35904,35907],{"class":94,"line":95},[92,35901,6327],{"class":98},[92,35903,5659],{"class":98},[92,35905,35906],{"class":5161}," roles",[92,35908,27470],{"class":119},[92,35910,35911],{"class":94,"line":106},[92,35912,11212],{"class":119},[92,35914,35915,35917,35919,35921,35923,35925,35927,35929,35931,35933,35936,35938,35941],{"class":94,"line":113},[92,35916,5195],{"class":98},[92,35918,6239],{"class":102},[92,35920,1996],{"class":98},[92,35922,34244],{"class":5161},[92,35924,120],{"class":119},[92,35926,34249],{"class":102},[92,35928,6985],{"class":98},[92,35930,5182],{"class":119},[92,35932,1996],{"class":98},[92,35934,35935],{"class":5161},"withPivot",[92,35937,120],{"class":119},[92,35939,35940],{"class":171},"'assigned_at'",[92,35942,6289],{"class":119},[92,35944,35945],{"class":94,"line":138},[92,35946,4711],{"class":119},[92,35948,35949],{"class":94,"line":143},[92,35950,110],{"emptyLinePlaceholder":109},[92,35952,35953],{"class":94,"line":149},[92,35954,35955],{"class":134},"// Access it:\n",[92,35957,35958,35960,35963,35965,35968,35970],{"class":94,"line":155},[92,35959,4394],{"class":98},[92,35961,35962],{"class":119}," ($user",[92,35964,1996],{"class":98},[92,35966,35967],{"class":119},"roles ",[92,35969,4497],{"class":98},[92,35971,35972],{"class":119}," $role) {\n",[92,35974,35975,35977,35980,35982,35984,35986],{"class":94,"line":161},[92,35976,5314],{"class":102},[92,35978,35979],{"class":119}," $role",[92,35981,1996],{"class":98},[92,35983,34253],{"class":119},[92,35985,1996],{"class":98},[92,35987,35988],{"class":119},"assigned_at;\n",[92,35990,35991],{"class":94,"line":166},[92,35992,4711],{"class":119},[11,35994,35995,35996,35999,36000,529,36003,36006],{},"You can also add ",[15,35997,35998],{},"withTimestamps()"," so the pivot auto-manages ",[15,36001,36002],{},"created_at",[15,36004,36005],{},"updated_at",". Understanding the pivot is key to working with many-to-many relationships correctly.",[242,36008,36010],{"id":36009},"_51-what-are-polymorphic-relationships","51. What are polymorphic relationships?",[11,36012,6686,36013,36016,36017,36019,36020,36022,36023,36025,36026,36029],{},[10490,36014,36015],{},"polymorphic relationship"," lets a single model belong to more than one other type of model using just one association. The classic example is comments: a ",[15,36018,34236],{}," might belong to a ",[15,36021,32529],{},", a ",[15,36024,34291],{},", or a ",[15,36027,36028],{},"Photo",", and you don't want a separate comments table for each.",[11,36031,36032,36033,36036,36037,36040],{},"Instead of many foreign keys, the comments table gets two columns: ",[15,36034,36035],{},"commentable_id"," (the related record's id) and ",[15,36038,36039],{},"commentable_type"," (which model class it is). The pair together identifies exactly what the comment belongs to.",[83,36042,36044],{"className":85,"code":36043,"language":87,"meta":88,"style":88},"class Comment extends Model\n{\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass Post extends Model\n{\n    public function comments()\n    {\n        return $this->morphMany(Comment::class, 'commentable');\n    }\n}\n",[15,36045,36046,36057,36061,36072,36076,36088,36092,36096,36100,36110,36114,36124,36128,36151,36155],{"__ignoreMap":88},[92,36047,36048,36050,36053,36055],{"class":94,"line":95},[92,36049,6122],{"class":98},[92,36051,36052],{"class":5161}," Comment",[92,36054,7096],{"class":98},[92,36056,34309],{"class":5161},[92,36058,36059],{"class":94,"line":106},[92,36060,11212],{"class":119},[92,36062,36063,36065,36067,36070],{"class":94,"line":113},[92,36064,6132],{"class":98},[92,36066,5659],{"class":98},[92,36068,36069],{"class":5161}," commentable",[92,36071,27470],{"class":119},[92,36073,36074],{"class":94,"line":138},[92,36075,11267],{"class":119},[92,36077,36078,36080,36082,36084,36086],{"class":94,"line":143},[92,36079,6236],{"class":98},[92,36081,6239],{"class":102},[92,36083,1996],{"class":98},[92,36085,34279],{"class":5161},[92,36087,7730],{"class":119},[92,36089,36090],{"class":94,"line":149},[92,36091,5104],{"class":119},[92,36093,36094],{"class":94,"line":155},[92,36095,4711],{"class":119},[92,36097,36098],{"class":94,"line":161},[92,36099,110],{"emptyLinePlaceholder":109},[92,36101,36102,36104,36106,36108],{"class":94,"line":166},[92,36103,6122],{"class":98},[92,36105,34304],{"class":5161},[92,36107,7096],{"class":98},[92,36109,34309],{"class":5161},[92,36111,36112],{"class":94,"line":187},[92,36113,11212],{"class":119},[92,36115,36116,36118,36120,36122],{"class":94,"line":217},[92,36117,6132],{"class":98},[92,36119,5659],{"class":98},[92,36121,34322],{"class":5161},[92,36123,27470],{"class":119},[92,36125,36126],{"class":94,"line":712},[92,36127,11267],{"class":119},[92,36129,36130,36132,36134,36136,36138,36140,36142,36144,36146,36149],{"class":94,"line":730},[92,36131,6236],{"class":98},[92,36133,6239],{"class":102},[92,36135,1996],{"class":98},[92,36137,34282],{"class":5161},[92,36139,120],{"class":119},[92,36141,34236],{"class":102},[92,36143,6985],{"class":98},[92,36145,195],{"class":119},[92,36147,36148],{"class":171},"'commentable'",[92,36150,6289],{"class":119},[92,36152,36153],{"class":94,"line":747},[92,36154,5104],{"class":119},[92,36156,36157],{"class":94,"line":763},[92,36158,4711],{"class":119},[11,36160,14550,36161,834,36164,36167,36168,36170],{},[15,36162,36163],{},"$post->comments",[15,36165,36166],{},"$video->comments"," both work through the same ",[15,36169,34236],{}," model. It keeps your schema clean when several unrelated models share the same kind of child records.",[242,36172,36174],{"id":36173},"_52-how-do-you-efficiently-process-very-large-result-sets","52. How do you efficiently process very large result sets?",[11,36176,36177,36178,36180],{},"Loading millions of rows at once with ",[15,36179,35466],{}," will exhaust your memory. Laravel provides ways to process big datasets in small pieces instead.",[11016,36182,36183],{},[11019,36184,36185,36188],{},[15,36186,36187],{},"chunk()"," fetches records in batches of a given size, running a callback on each batch:",[83,36190,36192],{"className":85,"code":36191,"language":87,"meta":88,"style":88},"User::chunk(500, function ($users) {\n    foreach ($users as $user) {\n        // process each user\n    }\n});\n",[15,36193,36194,36214,36226,36231,36235],{"__ignoreMap":88},[92,36195,36196,36198,36200,36203,36205,36207,36209,36211],{"class":94,"line":95},[92,36197,27917],{"class":102},[92,36199,6818],{"class":98},[92,36201,36202],{"class":5161},"chunk",[92,36204,120],{"class":119},[92,36206,9235],{"class":102},[92,36208,195],{"class":119},[92,36210,3556],{"class":98},[92,36212,36213],{"class":119}," ($users) {\n",[92,36215,36216,36218,36221,36223],{"class":94,"line":106},[92,36217,5031],{"class":98},[92,36219,36220],{"class":119}," ($users ",[92,36222,4497],{"class":98},[92,36224,36225],{"class":119}," $user) {\n",[92,36227,36228],{"class":94,"line":113},[92,36229,36230],{"class":134},"        // process each user\n",[92,36232,36233],{"class":94,"line":138},[92,36234,5104],{"class":119},[92,36236,36237],{"class":94,"line":143},[92,36238,11624],{"class":119},[11016,36240,36241,36251],{},[11019,36242,36243,36246,36247,36250],{},[15,36244,36245],{},"cursor()"," uses a database cursor and PHP generators to fetch ",[10490,36248,36249],{},"one row at a time",", keeping only a single model in memory (great for read-only iteration).",[11019,36252,36253,36256,36257,36260],{},[15,36254,36255],{},"lazy()"," is similar to chunk but gives you a single flat ",[15,36258,36259],{},"LazyCollection"," to iterate over.",[11,36262,36263],{},"The key idea is the same: never pull an enormous table fully into memory; stream it in manageable pieces so memory usage stays flat regardless of table size.",[242,36265,36267],{"id":36266},"_53-what-are-model-factories-and-seeders","53. What are model factories and seeders?",[11,36269,36270,36273,36274,36277],{},[10490,36271,36272],{},"Factories"," define blueprints for generating fake model data, and ",[10490,36275,36276],{},"seeders"," use them to populate your database. Together they let you fill your app with realistic test data quickly.",[11,36279,36280],{},"A factory describes what a fake model looks like, using the Faker library:",[83,36282,36284],{"className":85,"code":36283,"language":87,"meta":88,"style":88},"class UserFactory extends Factory\n{\n    public function definition(): array\n    {\n        return [\n            'name'  => fake()->name(),\n            'email' => fake()->unique()->safeEmail(),\n        ];\n    }\n}\n",[15,36285,36286,36298,36302,36317,36321,36327,36347,36372,36377,36381],{"__ignoreMap":88},[92,36287,36288,36290,36293,36295],{"class":94,"line":95},[92,36289,6122],{"class":98},[92,36291,36292],{"class":5161}," UserFactory",[92,36294,7096],{"class":98},[92,36296,36297],{"class":5161}," Factory\n",[92,36299,36300],{"class":94,"line":106},[92,36301,11212],{"class":119},[92,36303,36304,36306,36308,36311,36313,36315],{"class":94,"line":113},[92,36305,6132],{"class":98},[92,36307,5659],{"class":98},[92,36309,36310],{"class":5161}," definition",[92,36312,6042],{"class":119},[92,36314,5185],{"class":98},[92,36316,33625],{"class":98},[92,36318,36319],{"class":94,"line":138},[92,36320,11267],{"class":119},[92,36322,36323,36325],{"class":94,"line":143},[92,36324,6236],{"class":98},[92,36326,3034],{"class":119},[92,36328,36329,36332,36335,36338,36340,36342,36344],{"class":94,"line":149},[92,36330,36331],{"class":171},"            'name'",[92,36333,36334],{"class":98},"  =>",[92,36336,36337],{"class":5161}," fake",[92,36339,6042],{"class":119},[92,36341,1996],{"class":98},[92,36343,5271],{"class":5161},[92,36345,36346],{"class":119},"(),\n",[92,36348,36349,36352,36354,36356,36358,36360,36363,36365,36367,36370],{"class":94,"line":155},[92,36350,36351],{"class":171},"            'email'",[92,36353,1019],{"class":98},[92,36355,36337],{"class":5161},[92,36357,6042],{"class":119},[92,36359,1996],{"class":98},[92,36361,36362],{"class":5161},"unique",[92,36364,6042],{"class":119},[92,36366,1996],{"class":98},[92,36368,36369],{"class":5161},"safeEmail",[92,36371,36346],{"class":119},[92,36373,36374],{"class":94,"line":161},[92,36375,36376],{"class":119},"        ];\n",[92,36378,36379],{"class":94,"line":166},[92,36380,5104],{"class":119},[92,36382,36383],{"class":94,"line":187},[92,36384,4711],{"class":119},[11,36386,36387],{},"A seeder then creates many of them:",[83,36389,36391],{"className":85,"code":36390,"language":87,"meta":88,"style":88},"User::factory()->count(50)->create();\n",[15,36392,36393],{"__ignoreMap":88},[92,36394,36395,36397,36399,36401,36403,36405,36407,36409,36412,36414,36416,36418],{"class":94,"line":95},[92,36396,27917],{"class":102},[92,36398,6818],{"class":98},[92,36400,32170],{"class":5161},[92,36402,6042],{"class":119},[92,36404,1996],{"class":98},[92,36406,3243],{"class":5161},[92,36408,120],{"class":119},[92,36410,36411],{"class":102},"50",[92,36413,5182],{"class":119},[92,36415,1996],{"class":98},[92,36417,32177],{"class":5161},[92,36419,7730],{"class":119},[11,36421,36422,36423,36426],{},"Factories are essential in ",[10490,36424,36425],{},"testing"," (each test can spin up exactly the records it needs), and seeders are great for local development so you're not staring at an empty app.",[242,36428,36430,36431,834,36434,897],{"id":36429},"_54-what-is-the-difference-between-pluck-and-select","54. What is the difference between ",[15,36432,36433],{},"pluck()",[15,36435,36436],{},"select()",[11,36438,36439],{},"Both narrow down what you get back, but they operate differently.",[11,36441,36442,36444,36445,36448],{},[15,36443,36436],{}," limits ",[1511,36446,36447],{},"which columns"," the query fetches from the database, but you still get full model objects (with only those columns populated):",[83,36450,36452],{"className":85,"code":36451,"language":87,"meta":88,"style":88},"User::select('id', 'name')->get(); // collection of User models\n",[15,36453,36454],{"__ignoreMap":88},[92,36455,36456,36458,36460,36462,36464,36466,36468,36470,36472,36474,36476,36478],{"class":94,"line":95},[92,36457,27917],{"class":102},[92,36459,6818],{"class":98},[92,36461,29417],{"class":5161},[92,36463,120],{"class":119},[92,36465,32436],{"class":171},[92,36467,195],{"class":119},[92,36469,1016],{"class":171},[92,36471,5182],{"class":119},[92,36473,1996],{"class":98},[92,36475,8985],{"class":5161},[92,36477,27477],{"class":119},[92,36479,34125],{"class":134},[11,36481,36482,36484,36485,36488],{},[15,36483,36433],{}," returns a simple collection of a ",[10490,36486,36487],{},"single column's values"," (optionally keyed by another column), not model objects:",[83,36490,36492],{"className":85,"code":36491,"language":87,"meta":88,"style":88},"User::pluck('name');          // ['Alice', 'Bob', ...]\nUser::pluck('name', 'id');    // [1 => 'Alice', 2 => 'Bob']\n",[15,36493,36494,36512],{"__ignoreMap":88},[92,36495,36496,36498,36500,36503,36505,36507,36509],{"class":94,"line":95},[92,36497,27917],{"class":102},[92,36499,6818],{"class":98},[92,36501,36502],{"class":5161},"pluck",[92,36504,120],{"class":119},[92,36506,1016],{"class":171},[92,36508,571],{"class":119},[92,36510,36511],{"class":134},"// ['Alice', 'Bob', ...]\n",[92,36513,36514,36516,36518,36520,36522,36524,36526,36528,36530],{"class":94,"line":106},[92,36515,27917],{"class":102},[92,36517,6818],{"class":98},[92,36519,36502],{"class":5161},[92,36521,120],{"class":119},[92,36523,1016],{"class":171},[92,36525,195],{"class":119},[92,36527,32436],{"class":171},[92,36529,2770],{"class":119},[92,36531,36532],{"class":134},"// [1 => 'Alice', 2 => 'Bob']\n",[11,36534,36535,36536,36538,36539,36541],{},"Use ",[15,36537,36436],{}," when you want models but fewer columns for efficiency, and ",[15,36540,36433],{}," when you just want a flat list of values, like for a dropdown.",[39,36543,36545],{"id":36544},"migrations-and-database","Migrations and Database",[242,36547,36549],{"id":36548},"_55-what-are-migrations-and-why-are-they-useful","55. What are migrations, and why are they useful?",[11,36551,36552,36555],{},[10490,36553,36554],{},"Migrations"," are version control for your database schema. Each migration is a PHP file describing a change to the database (creating a table, adding a column), so your schema lives in code alongside your app.",[83,36557,36559],{"className":85,"code":36558,"language":87,"meta":88,"style":88},"Schema::create('posts', function (Blueprint $table) {\n    $table->id();\n    $table->string('title');\n    $table->text('body');\n    $table->timestamps();\n});\n",[15,36560,36561,36586,36597,36611,36626,36637],{"__ignoreMap":88},[92,36562,36563,36566,36568,36570,36572,36574,36576,36578,36580,36583],{"class":94,"line":95},[92,36564,36565],{"class":102},"Schema",[92,36567,6818],{"class":98},[92,36569,32177],{"class":5161},[92,36571,120],{"class":119},[92,36573,33310],{"class":171},[92,36575,195],{"class":119},[92,36577,3556],{"class":98},[92,36579,3559],{"class":119},[92,36581,36582],{"class":102},"Blueprint",[92,36584,36585],{"class":119}," $table) {\n",[92,36587,36588,36591,36593,36595],{"class":94,"line":106},[92,36589,36590],{"class":119},"    $table",[92,36592,1996],{"class":98},[92,36594,28803],{"class":5161},[92,36596,7730],{"class":119},[92,36598,36599,36601,36603,36605,36607,36609],{"class":94,"line":113},[92,36600,36590],{"class":119},[92,36602,1996],{"class":98},[92,36604,376],{"class":5161},[92,36606,120],{"class":119},[92,36608,33638],{"class":171},[92,36610,6289],{"class":119},[92,36612,36613,36615,36617,36620,36622,36624],{"class":94,"line":138},[92,36614,36590],{"class":119},[92,36616,1996],{"class":98},[92,36618,36619],{"class":5161},"text",[92,36621,120],{"class":119},[92,36623,33648],{"class":171},[92,36625,6289],{"class":119},[92,36627,36628,36630,36632,36635],{"class":94,"line":143},[92,36629,36590],{"class":119},[92,36631,1996],{"class":98},[92,36633,36634],{"class":5161},"timestamps",[92,36636,7730],{"class":119},[92,36638,36639],{"class":94,"line":149},[92,36640,11624],{"class":119},[11,36642,36643,36644,36647],{},"The big win is teamwork and consistency: instead of emailing SQL scripts around, everyone runs ",[15,36645,36646],{},"php artisan migrate"," and gets the exact same schema. It also makes changes reproducible across local, staging, and production environments, and gives you a clear history of how the schema evolved.",[242,36649,36651,36652,195,36655,195,36658,394,36661,897],{"id":36650},"_56-what-is-the-difference-between-migrate-migraterollback-migraterefresh-and-migratefresh","56. What is the difference between ",[15,36653,36654],{},"migrate",[15,36656,36657],{},"migrate:rollback",[15,36659,36660],{},"migrate:refresh",[15,36662,36663],{},"migrate:fresh",[11,36665,36666],{},"These commands manage the state of your migrations, and mixing them up in production can be dangerous, so it's worth knowing precisely.",[11016,36668,36669,36677,36689,36700],{},[11019,36670,36671,36673,36674,81],{},[15,36672,36654],{}," runs any migrations that ",[10490,36675,36676],{},"haven't run yet",[11019,36678,36679,1644,36681,36684,36685,36688],{},[15,36680,36657],{},[10490,36682,36683],{},"undoes"," the last batch of migrations by calling their ",[15,36686,36687],{},"down()"," methods.",[11019,36690,36691,1644,36693,36696,36697,36699],{},[15,36692,36660],{},[10490,36694,36695],{},"rolls back all"," migrations and then re-runs them (rollback + migrate), preserving the ",[15,36698,36687],{}," logic.",[11019,36701,36702,1644,36704,36707,36708,36710],{},[15,36703,36663],{},[10490,36705,36706],{},"drops all tables"," and re-runs every migration from scratch (it ignores ",[15,36709,36687],{}," entirely).",[11,36712,36713,36714,36717,36718,36720,36721,36724],{},"The critical distinction: ",[15,36715,36716],{},"refresh"," walks back through your ",[15,36719,36687],{}," methods, while ",[15,36722,36723],{},"fresh"," just wipes the whole database. Both destroy data, so they're for development only, never production.",[242,36726,36728],{"id":36727},"_57-how-do-you-define-foreign-key-constraints-in-a-migration","57. How do you define foreign key constraints in a migration?",[11,36730,6686,36731,36734,36735,36738],{},[10490,36732,36733],{},"foreign key"," enforces a relationship between tables at the database level, ensuring, for example, that a comment's ",[15,36736,36737],{},"post_id"," actually points to a real post. Laravel gives you a clean helper for this.",[83,36740,36742],{"className":85,"code":36741,"language":87,"meta":88,"style":88},"Schema::create('comments', function (Blueprint $table) {\n    $table->id();\n    $table->foreignId('post_id')\n        ->constrained()\n        ->onDelete('cascade');\n    $table->text('body');\n});\n",[15,36743,36744,36766,36776,36792,36802,36816,36830],{"__ignoreMap":88},[92,36745,36746,36748,36750,36752,36754,36756,36758,36760,36762,36764],{"class":94,"line":95},[92,36747,36565],{"class":102},[92,36749,6818],{"class":98},[92,36751,32177],{"class":5161},[92,36753,120],{"class":119},[92,36755,34601],{"class":171},[92,36757,195],{"class":119},[92,36759,3556],{"class":98},[92,36761,3559],{"class":119},[92,36763,36582],{"class":102},[92,36765,36585],{"class":119},[92,36767,36768,36770,36772,36774],{"class":94,"line":106},[92,36769,36590],{"class":119},[92,36771,1996],{"class":98},[92,36773,28803],{"class":5161},[92,36775,7730],{"class":119},[92,36777,36778,36780,36782,36785,36787,36790],{"class":94,"line":113},[92,36779,36590],{"class":119},[92,36781,1996],{"class":98},[92,36783,36784],{"class":5161},"foreignId",[92,36786,120],{"class":119},[92,36788,36789],{"class":171},"'post_id'",[92,36791,24307],{"class":119},[92,36793,36794,36797,36800],{"class":94,"line":138},[92,36795,36796],{"class":98},"        ->",[92,36798,36799],{"class":5161},"constrained",[92,36801,27470],{"class":119},[92,36803,36804,36806,36809,36811,36814],{"class":94,"line":143},[92,36805,36796],{"class":98},[92,36807,36808],{"class":5161},"onDelete",[92,36810,120],{"class":119},[92,36812,36813],{"class":171},"'cascade'",[92,36815,6289],{"class":119},[92,36817,36818,36820,36822,36824,36826,36828],{"class":94,"line":149},[92,36819,36590],{"class":119},[92,36821,1996],{"class":98},[92,36823,36619],{"class":5161},[92,36825,120],{"class":119},[92,36827,33648],{"class":171},[92,36829,6289],{"class":119},[92,36831,36832],{"class":94,"line":155},[92,36833,11624],{"class":119},[11,36835,36836,36839,36840,36843,36844,36846,36847,36850],{},[15,36837,36838],{},"foreignId('post_id')->constrained()"," creates the column and links it to the ",[15,36841,36842],{},"posts"," table's ",[15,36845,28803],{}," automatically (by convention). ",[15,36848,36849],{},"onDelete('cascade')"," says that when a post is deleted, its comments should be deleted too. This keeps your data consistent and prevents orphaned rows.",[242,36852,36854],{"id":36853},"_58-how-does-laravel-protect-against-sql-injection","58. How does Laravel protect against SQL injection?",[11,36856,36857,36860,36861,36864],{},[10490,36858,36859],{},"SQL injection"," is when an attacker sneaks malicious SQL into an input to manipulate your query. Laravel protects against it by using ",[10490,36862,36863],{},"parameter binding"," through PDO under the hood: user values are sent to the database separately from the SQL statement, so they're always treated as data, never as executable SQL.",[11,36866,36867],{},"Whenever you use Eloquent or the Query Builder, this happens automatically:",[83,36869,36871],{"className":85,"code":36870,"language":87,"meta":88,"style":88},"// Safe: the email is bound as a parameter, not concatenated into SQL\nUser::where('email', $request->email)->first();\n",[15,36872,36873,36878],{"__ignoreMap":88},[92,36874,36875],{"class":94,"line":95},[92,36876,36877],{"class":134},"// Safe: the email is bound as a parameter, not concatenated into SQL\n",[92,36879,36880,36882,36884,36886,36888,36890,36893,36895,36898,36900,36902],{"class":94,"line":106},[92,36881,27917],{"class":102},[92,36883,6818],{"class":98},[92,36885,34105],{"class":5161},[92,36887,120],{"class":119},[92,36889,34977],{"class":171},[92,36891,36892],{"class":119},", $request",[92,36894,1996],{"class":98},[92,36896,36897],{"class":119},"email)",[92,36899,1996],{"class":98},[92,36901,31695],{"class":5161},[92,36903,7730],{"class":119},[11,36905,36906,36907,36910,36911,36914,36915,36918],{},"The main way to ",[1511,36908,36909],{},"lose"," this protection is by writing raw queries that concatenate user input directly, like ",[15,36912,36913],{},"DB::raw(\"... = $input\")",". As long as you pass user input through bindings (",[15,36916,36917],{},"whereRaw('email = ?', [$input])",") or stick to the builder, you're safe by default.",[242,36920,36922],{"id":36921},"_59-what-are-database-transactions-in-laravel-and-how-do-you-use-them","59. What are database transactions in Laravel, and how do you use them?",[11,36924,6686,36925,36928],{},[10490,36926,36927],{},"transaction"," groups several database operations so they all succeed together or all fail together, leaving no half-finished state. If something throws an exception midway, everything rolls back.",[11,36930,36931,36932,36935],{},"The easiest way is the ",[15,36933,36934],{},"DB::transaction()"," closure, which commits automatically on success and rolls back on any exception:",[83,36937,36939],{"className":85,"code":36938,"language":87,"meta":88,"style":88},"DB::transaction(function () {\n    $order = Order::create([...]);\n    $order->items()->createMany([...]);\n    Inventory::decrement('stock', $qty);\n});\n",[15,36940,36941,36956,36976,36999,37017],{"__ignoreMap":88},[92,36942,36943,36946,36948,36950,36952,36954],{"class":94,"line":95},[92,36944,36945],{"class":102},"DB",[92,36947,6818],{"class":98},[92,36949,36927],{"class":5161},[92,36951,120],{"class":119},[92,36953,3556],{"class":98},[92,36955,32636],{"class":119},[92,36957,36958,36961,36963,36966,36968,36970,36972,36974],{"class":94,"line":106},[92,36959,36960],{"class":119},"    $order ",[92,36962,126],{"class":98},[92,36964,36965],{"class":102}," Order",[92,36967,6818],{"class":98},[92,36969,32177],{"class":5161},[92,36971,486],{"class":119},[92,36973,5335],{"class":98},[92,36975,11674],{"class":119},[92,36977,36978,36981,36983,36986,36988,36990,36993,36995,36997],{"class":94,"line":113},[92,36979,36980],{"class":119},"    $order",[92,36982,1996],{"class":98},[92,36984,36985],{"class":5161},"items",[92,36987,6042],{"class":119},[92,36989,1996],{"class":98},[92,36991,36992],{"class":5161},"createMany",[92,36994,486],{"class":119},[92,36996,5335],{"class":98},[92,36998,11674],{"class":119},[92,37000,37001,37004,37006,37009,37011,37014],{"class":94,"line":138},[92,37002,37003],{"class":102},"    Inventory",[92,37005,6818],{"class":98},[92,37007,37008],{"class":5161},"decrement",[92,37010,120],{"class":119},[92,37012,37013],{"class":171},"'stock'",[92,37015,37016],{"class":119},", $qty);\n",[92,37018,37019],{"class":94,"line":143},[92,37020,11624],{"class":119},[11,37022,37023],{},"If the inventory update fails, the order and its items are undone too, so you never end up with an order that has no items. This is essential for operations that must stay consistent, like transferring money or processing a multi-step checkout.",[39,37025,37027],{"id":37026},"blade-templating","Blade Templating",[242,37029,37031],{"id":37030},"_60-what-is-blade","60. What is Blade?",[11,37033,37034,37037,37038,834,37041,37044],{},[10490,37035,37036],{},"Blade"," is Laravel's templating engine, used to build the HTML views your users see. It lets you write clean templates with special directives (like ",[15,37039,37040],{},"@if",[15,37042,37043],{},"@foreach",") mixed into HTML, without the clutter of raw PHP tags everywhere.",[11,37046,37047,37048,3345,37050,37053],{},"Blade templates are compiled into plain PHP and cached, so they add virtually no runtime overhead. Its main benefits are readable syntax, template inheritance (so you define a layout once and reuse it), reusable components, and built-in protection against XSS when you echo data. Files live in ",[15,37049,31409],{},[15,37051,37052],{},".blade.php"," extension.",[242,37055,37057,37058,834,37061,897],{"id":37056},"_61-what-is-the-difference-between-and","61. What is the difference between ",[15,37059,37060],{},"{{ }}",[15,37062,37063],{},"{!! !!}",[11,37065,37066],{},"Both output data in a Blade template, but they differ in a security-critical way.",[11,37068,37069,1644,37072,37075],{},[15,37070,37071],{},"{{ $value }}",[10490,37073,37074],{},"escapes"," the output, converting HTML characters into harmless entities. This protects you from XSS (cross-site scripting) attacks, so it's the safe default you should use almost always.",[11,37077,37078,37081,37082,37085,37086,37089],{},[15,37079,37080],{},"{!! $value !!}"," outputs the value as ",[10490,37083,37084],{},"raw, unescaped HTML",". You'd only use it when you ",[1511,37087,37088],{},"intentionally"," want to render HTML (for example, content from a trusted rich-text editor).",[83,37091,37093],{"className":32783,"code":37092,"language":32785,"meta":88,"style":88},"{{ $comment }}   {{-- \u003Cscript> becomes harmless text --}}\n{!! $trustedHtml !!}  {{-- renders actual HTML --}}\n",[15,37094,37095,37107],{"__ignoreMap":88},[92,37096,37097,37099,37102,37104],{"class":94,"line":95},[92,37098,33973],{"class":102},[92,37100,37101],{"class":119}," $comment ",[92,37103,33982],{"class":102},[92,37105,37106],{"class":134},"   {{-- \u003Cscript> becomes harmless text --}}\n",[92,37108,37109,37112,37115,37118],{"class":94,"line":106},[92,37110,37111],{"class":102},"{!!",[92,37113,37114],{"class":119}," $trustedHtml ",[92,37116,37117],{"class":102},"!!}",[92,37119,37120],{"class":134},"  {{-- renders actual HTML --}}\n",[11,37122,37123,37124,37126,37127,37129],{},"The rule: use ",[15,37125,37060],{}," by default, and only reach for ",[15,37128,37063],{}," when you're certain the content is safe, because using it on user input opens an XSS hole.",[242,37131,37133,37134,195,37137,394,37140,897],{"id":37132},"_62-what-are-blade-layouts-using-extends-section-and-yield","62. What are Blade layouts using ",[15,37135,37136],{},"@extends",[15,37138,37139],{},"@section",[15,37141,37142],{},"@yield",[11,37144,37145],{},"Blade layouts let you define a common page skeleton once (header, footer, navigation) and have individual pages fill in just the parts that change, avoiding repetition across every view.",[11,37147,37148,37149,5185],{},"The layout defines placeholders with ",[15,37150,37142],{},[83,37152,37154],{"className":32783,"code":37153,"language":32785,"meta":88,"style":88},"{{-- layouts/app.blade.php --}}\n\u003Chtml>\n\u003Cbody>\n    \u003Cmain>@yield('content')\u003C/main>\n\u003C/body>\n\u003C/html>\n",[15,37155,37156,37161,37170,37179,37201,37209],{"__ignoreMap":88},[92,37157,37158],{"class":94,"line":95},[92,37159,37160],{"class":134},"{{-- layouts/app.blade.php --}}\n",[92,37162,37163,37165,37168],{"class":94,"line":106},[92,37164,4671],{"class":119},[92,37166,37167],{"class":2145},"html",[92,37169,2158],{"class":119},[92,37171,37172,37174,37177],{"class":94,"line":113},[92,37173,4671],{"class":119},[92,37175,37176],{"class":2145},"body",[92,37178,2158],{"class":119},[92,37180,37181,37183,37185,37187,37189,37191,37194,37197,37199],{"class":94,"line":138},[92,37182,2142],{"class":119},[92,37184,14906],{"class":2145},[92,37186,1599],{"class":119},[92,37188,37142],{"class":98},[92,37190,120],{"class":119},[92,37192,37193],{"class":171},"'content'",[92,37195,37196],{"class":119},")\u003C/",[92,37198,14906],{"class":2145},[92,37200,2158],{"class":119},[92,37202,37203,37205,37207],{"class":94,"line":143},[92,37204,2153],{"class":119},[92,37206,37176],{"class":2145},[92,37208,2158],{"class":119},[92,37210,37211,37213,37215],{"class":94,"line":149},[92,37212,2153],{"class":119},[92,37214,37167],{"class":2145},[92,37216,2158],{"class":119},[11,37218,37219,37220,5185],{},"A child page extends it and provides content for those placeholders with ",[15,37221,37139],{},[83,37223,37225],{"className":32783,"code":37224,"language":32785,"meta":88,"style":88},"@extends('layouts.app')\n\n@section('content')\n    \u003Ch1>Welcome\u003C/h1>\n@endsection\n",[15,37226,37227,37238,37242,37252,37266],{"__ignoreMap":88},[92,37228,37229,37231,37233,37236],{"class":94,"line":95},[92,37230,37136],{"class":98},[92,37232,120],{"class":119},[92,37234,37235],{"class":171},"'layouts.app'",[92,37237,24307],{"class":119},[92,37239,37240],{"class":94,"line":106},[92,37241,110],{"emptyLinePlaceholder":109},[92,37243,37244,37246,37248,37250],{"class":94,"line":113},[92,37245,37139],{"class":98},[92,37247,120],{"class":119},[92,37249,37193],{"class":171},[92,37251,24307],{"class":119},[92,37253,37254,37256,37259,37262,37264],{"class":94,"line":138},[92,37255,2142],{"class":119},[92,37257,37258],{"class":2145},"h1",[92,37260,37261],{"class":119},">Welcome\u003C/",[92,37263,37258],{"class":2145},[92,37265,2158],{"class":119},[92,37267,37268],{"class":94,"line":143},[92,37269,37270],{"class":98},"@endsection\n",[11,37272,37273,37274,834,37277,37280],{},"You can also use ",[15,37275,37276],{},"@stack",[15,37278,37279],{},"@push"," to inject page-specific scripts or styles into the layout. This inheritance model keeps your markup DRY. Newer Laravel also offers component-based layouts as an alternative approach.",[242,37282,37284],{"id":37283},"_63-what-are-blade-components-and-slots","63. What are Blade components and slots?",[11,37286,37287,37290],{},[10490,37288,37289],{},"Blade components"," are reusable pieces of UI (a button, a card, an alert) that you define once and reuse anywhere, with the ability to pass in data. They make templates modular, like small building blocks.",[83,37292,37294],{"className":32783,"code":37293,"language":32785,"meta":88,"style":88},"{{-- resources/views/components/alert.blade.php --}}\n\u003Cdiv class=\"alert alert-{{ $type }}\">\n    {{ $slot }}\n\u003C/div>\n",[15,37295,37296,37301,37327,37338],{"__ignoreMap":88},[92,37297,37298],{"class":94,"line":95},[92,37299,37300],{"class":134},"{{-- resources/views/components/alert.blade.php --}}\n",[92,37302,37303,37305,37308,37310,37312,37315,37317,37320,37323,37325],{"class":94,"line":106},[92,37304,4671],{"class":119},[92,37306,37307],{"class":2145},"div",[92,37309,7204],{"class":5161},[92,37311,126],{"class":119},[92,37313,37314],{"class":171},"\"alert alert-",[92,37316,33973],{"class":102},[92,37318,37319],{"class":119}," $type",[92,37321,37322],{"class":102}," }}",[92,37324,178],{"class":171},[92,37326,2158],{"class":119},[92,37328,37329,37332,37335],{"class":94,"line":113},[92,37330,37331],{"class":102},"    {{",[92,37333,37334],{"class":119}," $slot ",[92,37336,37337],{"class":102},"}}\n",[92,37339,37340,37342,37344],{"class":94,"line":138},[92,37341,2153],{"class":119},[92,37343,37307],{"class":2145},[92,37345,2158],{"class":119},[11,37347,37348,37349,5185],{},"You use it as a custom HTML-like tag, and whatever you put inside becomes the ",[15,37350,37351],{},"$slot",[83,37353,37355],{"className":32783,"code":37354,"language":32785,"meta":88,"style":88},"\u003Cx-alert type=\"danger\">\n    Something went wrong!\n\u003C/x-alert>\n",[15,37356,37357,37374,37379],{"__ignoreMap":88},[92,37358,37359,37361,37364,37367,37369,37372],{"class":94,"line":95},[92,37360,4671],{"class":119},[92,37362,37363],{"class":2145},"x-alert",[92,37365,37366],{"class":5161}," type",[92,37368,126],{"class":119},[92,37370,37371],{"class":171},"\"danger\"",[92,37373,2158],{"class":119},[92,37375,37376],{"class":94,"line":106},[92,37377,37378],{"class":119},"    Something went wrong!\n",[92,37380,37381,37383,37385],{"class":94,"line":113},[92,37382,2153],{"class":119},[92,37384,37363],{"class":2145},[92,37386,2158],{"class":119},[11,37388,1792,37389,37391,37392,37395],{},[15,37390,37351],{}," is the main content passed between the tags. Components can also have named slots (for a title and body, say) and can be class-backed for more logic. They're the modern, cleaner alternative to ",[15,37393,37394],{},"@include"," for building a component library.",[242,37397,37399,37400,37402],{"id":37398},"_64-what-is-the-difference-between-include-and-a-blade-component","64. What is the difference between ",[15,37401,37394],{}," and a Blade component?",[11,37404,37405],{},"Both let you reuse a piece of a view, but they work differently.",[11,37407,37408,37410,37411,37414],{},[15,37409,37394],{}," simply pulls another Blade file into the current one, and that partial ",[10490,37412,37413],{},"shares all the variables"," of the parent view by default. It's a straightforward \"paste this file here\" tool, fine for simple partials.",[11,37416,6686,37417,37420],{},[10490,37418,37419],{},"component"," is more encapsulated: it has its own isolated data (you pass in exactly the props it needs), supports slots for content, and can be backed by a class with logic. It behaves like a self-contained widget rather than an inlined snippet.",[11,37422,36535,37423,37425],{},[15,37424,37394],{}," for a quick, dumb partial that just needs the parent's data; use a component when you want a reusable, well-defined element with a clear interface, which scales better as the app grows.",[242,37427,37429,37430,195,37433,394,37436,32126],{"id":37428},"_65-what-do-directives-like-forelse-isset-and-auth-do","65. What do directives like ",[15,37431,37432],{},"@forelse",[15,37434,37435],{},"@isset",[15,37437,37438],{},"@auth",[11,37440,37441],{},"Blade has many convenience directives that make templates cleaner than writing raw PHP conditions. A few common ones:",[11016,37443,37444],{},[11019,37445,37446,37449],{},[15,37447,37448],{},"@forelse ... @empty ... @endforelse"," loops over a collection but has a built-in fallback for when it's empty:",[83,37451,37453],{"className":32783,"code":37452,"language":32785,"meta":88,"style":88},"@forelse ($posts as $post)\n    \u003Cli>{{ $post->title }}\u003C/li>\n@empty\n    \u003Cli>No posts yet.\u003C/li>\n@endforelse\n",[15,37454,37455,37468,37493,37498,37511],{"__ignoreMap":88},[92,37456,37457,37460,37463,37465],{"class":94,"line":95},[92,37458,37459],{"class":98},"@forelse ",[92,37461,37462],{"class":119},"($posts ",[92,37464,4497],{"class":98},[92,37466,37467],{"class":119}," $post)\n",[92,37469,37470,37472,37474,37476,37478,37480,37482,37485,37487,37489,37491],{"class":94,"line":106},[92,37471,2142],{"class":119},[92,37473,11019],{"class":2145},[92,37475,1599],{"class":119},[92,37477,33973],{"class":102},[92,37479,34436],{"class":119},[92,37481,1996],{"class":98},[92,37483,37484],{"class":119},"title ",[92,37486,33982],{"class":102},[92,37488,2153],{"class":119},[92,37490,11019],{"class":2145},[92,37492,2158],{"class":119},[92,37494,37495],{"class":94,"line":113},[92,37496,37497],{"class":98},"@empty\n",[92,37499,37500,37502,37504,37507,37509],{"class":94,"line":138},[92,37501,2142],{"class":119},[92,37503,11019],{"class":2145},[92,37505,37506],{"class":119},">No posts yet.\u003C/",[92,37508,11019],{"class":2145},[92,37510,2158],{"class":119},[92,37512,37513],{"class":94,"line":143},[92,37514,37515],{"class":98},"@endforelse\n",[11016,37517,37518,37528],{},[11019,37519,37520,37523,37524,37527],{},[15,37521,37522],{},"@isset($var)"," renders its block only if the variable is set (and not null), and ",[15,37525,37526],{},"@empty($var)"," checks the opposite.",[11019,37529,37530,834,37532,37535,37536,37538,37539,81],{},[15,37531,37438],{},[15,37533,37534],{},"@guest"," render content based on whether the user is logged in, so you can show a \"Dashboard\" link to authenticated users and a \"Login\" link to guests without writing an ",[15,37537,4588],{}," around ",[15,37540,37541],{},"auth()->check()",[11,37543,37544],{},"These directives express common view logic more readably and are worth knowing because they come up constantly in real templates.",[39,37546,37548],{"id":37547},"authentication-and-authorization","Authentication and Authorization",[242,37550,37552],{"id":37551},"_66-how-does-authentication-work-in-laravel","66. How does authentication work in Laravel?",[11,37554,37555,37558,37559,37562],{},[10490,37556,37557],{},"Authentication"," is the process of verifying who a user is (logging them in). Laravel handles the heavy lifting: it provides the ",[15,37560,37561],{},"Auth"," system, session management, password hashing, and helpers to check the logged-in user.",[11,37564,37565,37566,37569,37570,37572,37573,37575],{},"At a high level, when a user submits valid credentials, Laravel verifies the password against the stored hash and, if it matches, marks them as authenticated (storing their identity in the session for web apps, or issuing a token for APIs). You then access the current user with ",[15,37567,37568],{},"auth()->user()"," or the ",[15,37571,37561],{}," facade, and protect routes with the ",[15,37574,32917],{}," middleware. Rather than building all this from scratch, you typically use a starter kit that scaffolds the login, registration, and password reset flows for you.",[242,37577,37579],{"id":37578},"_67-what-are-the-official-auth-starter-kits-and-how-do-they-differ","67. What are the official auth starter kits, and how do they differ?",[11,37581,37582],{},"Laravel offers a few first-party packages to scaffold authentication so you don't build it from zero. The main ones:",[11016,37584,37585,37591,37597],{},[11019,37586,37587,37590],{},[10490,37588,37589],{},"Breeze"," is the simplest: minimal, easy to read, with login, registration, password reset, and email verification. Great for learning and for straightforward apps. It comes in Blade, React/Vue (Inertia), or API flavors.",[11019,37592,37593,37596],{},[10490,37594,37595],{},"Jetstream"," is more feature-rich: it adds two-factor authentication, session management, team support, and profile management, built on Livewire or Inertia.",[11019,37598,37599,34946,37602,37605],{},[10490,37600,37601],{},"Fortify",[10490,37603,37604],{},"headless"," backend-only implementation (no views). It provides the authentication logic and routes, and you build your own UI on top. Jetstream actually uses Fortify under the hood.",[11,37607,37608],{},"You'd pick Breeze to start simple, Jetstream when you need those extra features out of the box, and Fortify when you want full control over the frontend.",[242,37610,37612],{"id":37611},"_68-what-is-laravel-sanctum-and-when-should-you-use-it","68. What is Laravel Sanctum, and when should you use it?",[11,37614,37615,37618,37619,37622,37623,37626],{},[10490,37616,37617],{},"Sanctum"," is Laravel's lightweight package for API authentication. It handles two main use cases: issuing simple ",[10490,37620,37621],{},"API tokens"," for things like mobile apps or third-party access, and ",[10490,37624,37625],{},"SPA authentication"," where a JavaScript frontend (React, Vue) talks to your Laravel backend using cookies.",[83,37628,37630],{"className":85,"code":37629,"language":87,"meta":88,"style":88},"// Issue a token\n$token = $user->createToken('mobile-app')->plainTextToken;\n\n// Protect a route\nRoute::middleware('auth:sanctum')->get('/user', fn (Request $r) => $r->user());\n",[15,37631,37632,37637,37663,37667,37672],{"__ignoreMap":88},[92,37633,37634],{"class":94,"line":95},[92,37635,37636],{"class":134},"// Issue a token\n",[92,37638,37639,37642,37644,37646,37648,37651,37653,37656,37658,37660],{"class":94,"line":106},[92,37640,37641],{"class":119},"$token ",[92,37643,126],{"class":98},[92,37645,1772],{"class":119},[92,37647,1996],{"class":98},[92,37649,37650],{"class":5161},"createToken",[92,37652,120],{"class":119},[92,37654,37655],{"class":171},"'mobile-app'",[92,37657,5182],{"class":119},[92,37659,1996],{"class":98},[92,37661,37662],{"class":119},"plainTextToken;\n",[92,37664,37665],{"class":94,"line":113},[92,37666,110],{"emptyLinePlaceholder":109},[92,37668,37669],{"class":94,"line":138},[92,37670,37671],{"class":134},"// Protect a route\n",[92,37673,37674,37676,37678,37680,37682,37685,37687,37689,37691,37693,37696,37698,37700,37702,37704,37707,37709,37711],{"class":94,"line":143},[92,37675,11466],{"class":102},[92,37677,6818],{"class":98},[92,37679,31476],{"class":5161},[92,37681,120],{"class":119},[92,37683,37684],{"class":171},"'auth:sanctum'",[92,37686,5182],{"class":119},[92,37688,1996],{"class":98},[92,37690,8985],{"class":5161},[92,37692,120],{"class":119},[92,37694,37695],{"class":171},"'/user'",[92,37697,195],{"class":119},[92,37699,3466],{"class":98},[92,37701,3559],{"class":119},[92,37703,11537],{"class":102},[92,37705,37706],{"class":119}," $r) => $r",[92,37708,1996],{"class":98},[92,37710,33170],{"class":5161},[92,37712,9268],{"class":119},[11,37714,37715],{},"You reach for Sanctum when you need straightforward API authentication without the complexity of full OAuth. For most apps (a mobile client, or a first-party SPA), it's the recommended choice because it's simple and covers the common needs.",[242,37717,37719],{"id":37718},"_69-what-is-laravel-passport-and-how-is-it-different-from-sanctum","69. What is Laravel Passport, and how is it different from Sanctum?",[11,37721,37722,37725,37726,37729,37730,81],{},[10490,37723,37724],{},"Passport"," is a full ",[10490,37727,37728],{},"OAuth2"," server implementation for Laravel. It's heavier and more complex than Sanctum, providing the complete OAuth2 flow with authorization codes, access and refresh tokens, scopes, and the ability for third-party applications to request access on a user's behalf. Its access tokens are JWTs, so for how those are structured, signed, and verified under the hood, see ",[23,37731,37733],{"href":37732},"/post/everything-about-json-web-tokens-explained","Everything You Actually Need to Know About JWT",[11,37735,37736,37737,37739,37740,37742],{},"The difference comes down to needs. ",[10490,37738,37617],{}," is for simple token or SPA authentication (most apps). ",[10490,37741,37724],{}," is for when you genuinely need OAuth2, for example, you're building a public API that external developers will integrate with, and you need standardized OAuth flows. As a rule of thumb: start with Sanctum, and only move to Passport if you specifically require OAuth2 features. Using Passport when you just need simple tokens is overkill.",[242,37744,37746],{"id":37745},"_70-what-are-guards-and-providers-in-the-auth-config","70. What are guards and providers in the auth config?",[11,37748,37749,37750,37753,37754,37756,37757,37759],{},"These are two concepts in ",[15,37751,37752],{},"config/auth.php"," that define ",[1511,37755,7649],{}," users are authenticated and ",[1511,37758,34105],{}," they come from.",[11,37761,6686,37762,37765,37766,37768,37769,6339,37772,37774],{},[10490,37763,37764],{},"guard"," defines how users are authenticated for each request. The ",[15,37767,12369],{}," guard uses sessions and cookies; the ",[15,37770,37771],{},"sanctum",[15,37773,32739],{}," guard uses tokens. Guards let one app authenticate different clients in different ways.",[11,37776,6686,37777,37779,37780,37782,37783,34254],{},[10490,37778,11868],{}," defines how users are actually retrieved from storage, for example the ",[15,37781,35867],{}," provider using Eloquent to fetch from the ",[15,37784,35867],{},[83,37786,37788],{"className":85,"code":37787,"language":87,"meta":88,"style":88},"'guards' => [\n    'web' => ['driver' => 'session', 'provider' => 'users'],\n],\n'providers' => [\n    'users' => ['driver' => 'eloquent', 'model' => App\\Models\\User::class],\n],\n",[15,37789,37790,37799,37828,37832,37841,37871],{"__ignoreMap":88},[92,37791,37792,37795,37797],{"class":94,"line":95},[92,37793,37794],{"class":171},"'guards'",[92,37796,1019],{"class":98},[92,37798,3034],{"class":119},[92,37800,37801,37804,37806,37808,37811,37813,37816,37818,37821,37823,37826],{"class":94,"line":106},[92,37802,37803],{"class":171},"    'web'",[92,37805,1019],{"class":98},[92,37807,347],{"class":119},[92,37809,37810],{"class":171},"'driver'",[92,37812,1019],{"class":98},[92,37814,37815],{"class":171}," 'session'",[92,37817,195],{"class":119},[92,37819,37820],{"class":171},"'provider'",[92,37822,1019],{"class":98},[92,37824,37825],{"class":171}," 'users'",[92,37827,3083],{"class":119},[92,37829,37830],{"class":94,"line":113},[92,37831,3083],{"class":119},[92,37833,37834,37837,37839],{"class":94,"line":138},[92,37835,37836],{"class":171},"'providers'",[92,37838,1019],{"class":98},[92,37840,3034],{"class":119},[92,37842,37843,37846,37848,37850,37852,37854,37857,37859,37862,37864,37867,37869],{"class":94,"line":143},[92,37844,37845],{"class":171},"    'users'",[92,37847,1019],{"class":98},[92,37849,347],{"class":119},[92,37851,37810],{"class":171},[92,37853,1019],{"class":98},[92,37855,37856],{"class":171}," 'eloquent'",[92,37858,195],{"class":119},[92,37860,37861],{"class":171},"'model'",[92,37863,1019],{"class":98},[92,37865,37866],{"class":102}," App\\Models\\User",[92,37868,6985],{"class":98},[92,37870,3083],{"class":119},[92,37872,37873],{"class":94,"line":149},[92,37874,3083],{"class":119},[11,37876,37877],{},"So a guard answers \"how do I check who this is?\" and a provider answers \"where do I look them up?\" You can define multiple guards if, say, admins and customers live in different tables.",[242,37879,37881],{"id":37880},"_71-what-is-the-difference-between-authentication-and-authorization-in-laravel","71. What is the difference between authentication and authorization in Laravel?",[11,37883,37884,37885,37887,37888,37891,37892,37887,37895,37898],{},"They sound similar but answer different questions. ",[10490,37886,37557],{}," is \"",[1511,37889,37890],{},"who are you?","\", verifying identity through login. ",[10490,37893,37894],{},"Authorization",[1511,37896,37897],{},"what are you allowed to do?","\", checking permissions once we know who someone is.",[11,37900,37901,37902,37904,37905,37907,37908,834,37911,37914,37915,37569,37918,37921],{},"In Laravel, authentication is handled by the ",[15,37903,37561],{}," system, guards, and the ",[15,37906,32917],{}," middleware. Authorization is handled by ",[10490,37909,37910],{},"Gates",[10490,37912,37913],{},"Policies",", which you check with methods like ",[15,37916,37917],{},"$user->can('update', $post)",[15,37919,37920],{},"@can"," Blade directive. A user can be authenticated (logged in) but not authorized (not allowed to delete someone else's post). Interviewers ask this to make sure you don't conflate logging in with having permission.",[242,37923,37925],{"id":37924},"_72-what-are-gates","72. What are Gates?",[11,37927,37928,37930,37931,6339,37933,81],{},[10490,37929,37910],{}," are simple, closure-based checks for authorizing actions that aren't tied to a specific model. You define them (usually in a service provider) with a name and a closure that returns ",[15,37932,474],{},[15,37934,2300],{},[83,37936,37938],{"className":85,"code":37937,"language":87,"meta":88,"style":88},"Gate::define('access-admin', function (User $user) {\n    return $user->is_admin;\n});\n\n// Check it\nif (Gate::allows('access-admin')) {\n    // user can access the admin area\n}\n",[15,37939,37940,37964,37975,37979,37983,37988,38008,38013],{"__ignoreMap":88},[92,37941,37942,37945,37947,37949,37951,37954,37956,37958,37960,37962],{"class":94,"line":95},[92,37943,37944],{"class":102},"Gate",[92,37946,6818],{"class":98},[92,37948,866],{"class":5161},[92,37950,120],{"class":119},[92,37952,37953],{"class":171},"'access-admin'",[92,37955,195],{"class":119},[92,37957,3556],{"class":98},[92,37959,3559],{"class":119},[92,37961,27917],{"class":102},[92,37963,36225],{"class":119},[92,37965,37966,37968,37970,37972],{"class":94,"line":106},[92,37967,5195],{"class":98},[92,37969,1772],{"class":119},[92,37971,1996],{"class":98},[92,37973,37974],{"class":119},"is_admin;\n",[92,37976,37977],{"class":94,"line":113},[92,37978,11624],{"class":119},[92,37980,37981],{"class":94,"line":138},[92,37982,110],{"emptyLinePlaceholder":109},[92,37984,37985],{"class":94,"line":143},[92,37986,37987],{"class":134},"// Check it\n",[92,37989,37990,37992,37994,37996,37998,38001,38003,38005],{"class":94,"line":149},[92,37991,4588],{"class":98},[92,37993,3559],{"class":119},[92,37995,37944],{"class":102},[92,37997,6818],{"class":98},[92,37999,38000],{"class":5161},"allows",[92,38002,120],{"class":119},[92,38004,37953],{"class":171},[92,38006,38007],{"class":119},")) {\n",[92,38009,38010],{"class":94,"line":155},[92,38011,38012],{"class":134},"    // user can access the admin area\n",[92,38014,38015],{"class":94,"line":161},[92,38016,4711],{"class":119},[11,38018,38019,38020,37569,38023,38026],{},"You can also check with ",[15,38021,38022],{},"$user->can('access-admin')",[15,38024,38025],{},"@can('access-admin')"," Blade directive. Gates are best for broad, app-wide permissions (like \"can view the dashboard\") that don't revolve around a particular record.",[242,38028,38030],{"id":38029},"_73-what-are-policies-and-when-do-you-use-them-over-gates","73. What are Policies, and when do you use them over Gates?",[11,38032,38033,38035,38036,38039,38040,195,38043,195,38045,38047],{},[10490,38034,37913],{}," are classes that organize authorization logic around a specific model. Where a gate is a standalone closure, a policy groups all the permission checks for one model (a ",[15,38037,38038],{},"PostPolicy"," holds ",[15,38041,38042],{},"view",[15,38044,33287],{},[15,38046,26291],{},", and so on).",[83,38049,38051],{"className":85,"code":38050,"language":87,"meta":88,"style":88},"class PostPolicy\n{\n    public function update(User $user, Post $post): bool\n    {\n        return $user->id === $post->user_id;\n    }\n}\n\n// Check it\n$this->authorize('update', $post); // in a controller\n",[15,38052,38053,38060,38064,38089,38093,38112,38116,38120,38124,38128],{"__ignoreMap":88},[92,38054,38055,38057],{"class":94,"line":95},[92,38056,6122],{"class":98},[92,38058,38059],{"class":5161}," PostPolicy\n",[92,38061,38062],{"class":94,"line":106},[92,38063,11212],{"class":119},[92,38065,38066,38068,38070,38073,38075,38077,38080,38082,38085,38087],{"class":94,"line":113},[92,38067,6132],{"class":98},[92,38069,5659],{"class":98},[92,38071,38072],{"class":5161}," update",[92,38074,120],{"class":119},[92,38076,27917],{"class":102},[92,38078,38079],{"class":119}," $user, ",[92,38081,32529],{"class":102},[92,38083,38084],{"class":119}," $post)",[92,38086,5185],{"class":98},[92,38088,33568],{"class":98},[92,38090,38091],{"class":94,"line":138},[92,38092,11267],{"class":119},[92,38094,38095,38097,38099,38101,38103,38105,38107,38109],{"class":94,"line":143},[92,38096,6236],{"class":98},[92,38098,1772],{"class":119},[92,38100,1996],{"class":98},[92,38102,7786],{"class":119},[92,38104,1352],{"class":98},[92,38106,34436],{"class":119},[92,38108,1996],{"class":98},[92,38110,38111],{"class":119},"user_id;\n",[92,38113,38114],{"class":94,"line":149},[92,38115,5104],{"class":119},[92,38117,38118],{"class":94,"line":155},[92,38119,4711],{"class":119},[92,38121,38122],{"class":94,"line":161},[92,38123,110],{"emptyLinePlaceholder":109},[92,38125,38126],{"class":94,"line":166},[92,38127,37987],{"class":134},[92,38129,38130,38132,38134,38137,38139,38142,38145],{"class":94,"line":187},[92,38131,6100],{"class":102},[92,38133,1996],{"class":98},[92,38135,38136],{"class":5161},"authorize",[92,38138,120],{"class":119},[92,38140,38141],{"class":171},"'update'",[92,38143,38144],{"class":119},", $post); ",[92,38146,38147],{"class":134},"// in a controller\n",[11,38149,38150,38151,38154,38155,38158,38159,38161,38162,38165],{},"You use a ",[10490,38152,38153],{},"policy"," when authorization is about a model and its ownership (can ",[1511,38156,38157],{},"this"," user edit ",[1511,38160,38157],{}," post?), and a ",[10490,38163,38164],{},"gate"," for simpler, model-independent checks. Policies keep model-related permission rules tidy and discoverable in one class instead of scattered closures.",[242,38167,38169],{"id":38168},"_74-how-does-laravel-hash-and-store-passwords","74. How does Laravel hash and store passwords?",[11,38171,38172,38173,38176,38177,38180],{},"Laravel never stores passwords in plain text. It ",[10490,38174,38175],{},"hashes"," them using the ",[10490,38178,38179],{},"bcrypt"," algorithm by default (Argon2 is also available), which is a slow, one-way function designed specifically for passwords.",[83,38182,38184],{"className":85,"code":38183,"language":87,"meta":88,"style":88},"use Illuminate\\Support\\Facades\\Hash;\n\n$user->password = Hash::make($request->password); // store the hash\n\n// Later, to verify at login:\nHash::check($request->password, $user->password); // true or false\n",[15,38185,38186,38195,38199,38227,38231,38236],{"__ignoreMap":88},[92,38187,38188,38190,38193],{"class":94,"line":95},[92,38189,5612],{"class":98},[92,38191,38192],{"class":102}," Illuminate\\Support\\Facades\\Hash",[92,38194,229],{"class":119},[92,38196,38197],{"class":94,"line":106},[92,38198,110],{"emptyLinePlaceholder":109},[92,38200,38201,38203,38205,38208,38210,38213,38215,38217,38219,38221,38224],{"class":94,"line":113},[92,38202,2078],{"class":119},[92,38204,1996],{"class":98},[92,38206,38207],{"class":119},"password ",[92,38209,126],{"class":98},[92,38211,38212],{"class":102}," Hash",[92,38214,6818],{"class":98},[92,38216,26148],{"class":5161},[92,38218,31612],{"class":119},[92,38220,1996],{"class":98},[92,38222,38223],{"class":119},"password); ",[92,38225,38226],{"class":134},"// store the hash\n",[92,38228,38229],{"class":94,"line":138},[92,38230,110],{"emptyLinePlaceholder":109},[92,38232,38233],{"class":94,"line":143},[92,38234,38235],{"class":134},"// Later, to verify at login:\n",[92,38237,38238,38241,38243,38246,38248,38250,38253,38255,38257],{"class":94,"line":149},[92,38239,38240],{"class":102},"Hash",[92,38242,6818],{"class":98},[92,38244,38245],{"class":5161},"check",[92,38247,31612],{"class":119},[92,38249,1996],{"class":98},[92,38251,38252],{"class":119},"password, $user",[92,38254,1996],{"class":98},[92,38256,38223],{"class":119},[92,38258,38259],{"class":134},"// true or false\n",[11,38261,38262,38263,38265],{},"Because hashing is one-way, you can't reverse a hash back into the original password; at login you hash the attempt and compare. Bcrypt is deliberately slow and includes an automatic random salt per password, which makes brute-force and precomputed attacks impractical. Laravel's auth scaffolding does all this for you, so you rarely call ",[15,38264,38240],{}," directly except when building custom flows.",[39,38267,38269],{"id":38268},"events-queues-and-scheduling","Events, Queues, and Scheduling",[242,38271,38273],{"id":38272},"_75-what-are-events-and-listeners-in-laravel","75. What are events and listeners in Laravel?",[11,38275,38276,834,38279,38282,38283,38286,38287,38290,38291,38293],{},[10490,38277,38278],{},"Events",[10490,38280,38281],{},"listeners"," implement the observer pattern, letting you decouple parts of your application. An ",[10490,38284,38285],{},"event"," announces that something happened (like ",[15,38288,38289],{},"OrderShipped","), and one or more ",[10490,38292,38281],{}," react to it, without the code that fired the event needing to know who's listening.",[83,38295,38297],{"className":85,"code":38296,"language":87,"meta":88,"style":88},"// Fire an event\nOrderShipped::dispatch($order);\n\n// A listener reacts to it\nclass SendShipmentNotification\n{\n    public function handle(OrderShipped $event)\n    {\n        // notify the customer\n    }\n}\n",[15,38298,38299,38304,38315,38319,38324,38331,38335,38350,38354,38359,38363],{"__ignoreMap":88},[92,38300,38301],{"class":94,"line":95},[92,38302,38303],{"class":134},"// Fire an event\n",[92,38305,38306,38308,38310,38312],{"class":94,"line":106},[92,38307,38289],{"class":102},[92,38309,6818],{"class":98},[92,38311,11722],{"class":5161},[92,38313,38314],{"class":119},"($order);\n",[92,38316,38317],{"class":94,"line":113},[92,38318,110],{"emptyLinePlaceholder":109},[92,38320,38321],{"class":94,"line":138},[92,38322,38323],{"class":134},"// A listener reacts to it\n",[92,38325,38326,38328],{"class":94,"line":143},[92,38327,6122],{"class":98},[92,38329,38330],{"class":5161}," SendShipmentNotification\n",[92,38332,38333],{"class":94,"line":149},[92,38334,11212],{"class":119},[92,38336,38337,38339,38341,38343,38345,38347],{"class":94,"line":155},[92,38338,6132],{"class":98},[92,38340,5659],{"class":98},[92,38342,11255],{"class":5161},[92,38344,120],{"class":119},[92,38346,38289],{"class":102},[92,38348,38349],{"class":119}," $event)\n",[92,38351,38352],{"class":94,"line":161},[92,38353,11267],{"class":119},[92,38355,38356],{"class":94,"line":166},[92,38357,38358],{"class":134},"        // notify the customer\n",[92,38360,38361],{"class":94,"line":187},[92,38362,5104],{"class":119},[92,38364,38365],{"class":94,"line":217},[92,38366,4711],{"class":119},[11,38368,38369],{},"The benefit is separation of concerns: your checkout code just says \"an order shipped,\" and separate listeners handle emailing the customer, updating analytics, and notifying the warehouse. You can add or remove listeners without touching the code that fires the event, which keeps things flexible and clean.",[242,38371,38373],{"id":38372},"_76-what-is-the-difference-between-an-observer-and-an-event-listener","76. What is the difference between an observer and an event listener?",[11,38375,38376],{},"Both react to something happening, but they're scoped differently.",[11,38378,26615,38379,38381,38382,38385,38386,195,38388,195,38391,38393],{},[10490,38380,35253],{}," is specifically tied to a ",[10490,38383,38384],{},"model's"," lifecycle events (",[15,38387,35241],{},[15,38389,38390],{},"updated",[15,38392,35247],{},"). It's the natural choice when your logic responds to database changes on a particular model, and its methods map directly to those model events.",[11,38395,26615,38396,38399,38400,38403,38404,38407],{},[10490,38397,38398],{},"event listener"," responds to ",[10490,38401,38402],{},"any custom event"," you define anywhere in your app, not just model changes. It's more general-purpose: you dispatch an event manually (like ",[15,38405,38406],{},"PaymentReceived",") and the listener handles it.",[11,38409,38410,38411,38413,38414,38417],{},"In short, use an ",[10490,38412,35253],{}," for \"when this model changes,\" and an ",[10490,38415,38416],{},"event/listener"," for broader \"when this business thing happens.\" Observers are really a specialized, model-focused convenience built on the same event system.",[242,38419,38421],{"id":38420},"_77-what-are-queues-and-what-problem-do-they-solve","77. What are queues, and what problem do they solve?",[11,38423,6686,38424,38427],{},[10490,38425,38426],{},"queue"," lets you defer time-consuming tasks to be processed in the background, instead of making the user wait for them during a web request. Things like sending emails, processing images, or calling a slow external API don't need to block the response.",[11,38429,38430,38431,38433],{},"Without a queue, a user submitting a form that sends an email waits for the email to send before seeing \"Success.\" With a queue, you push the email onto the queue and respond instantly; a separate ",[10490,38432,12413],{}," process picks it up and sends it a moment later. This makes your app feel fast and helps it handle spikes in load, because heavy work is spread out and processed steadily rather than all at once.",[11,38435,38436],{},[3108,38437],{"alt":38438,"src":38439},"Laravel queue and job lifecycle diagram","/post-images/top-111-laravel-interview-questions/laravel-queue-lifecycle-diagram.png",[242,38441,38443],{"id":38442},"_78-what-is-a-job-and-how-do-you-dispatch-one","78. What is a Job, and how do you dispatch one?",[11,38445,6686,38446,38449,38450,38453,38454,38456],{},[10490,38447,38448],{},"Job"," is a class that represents a single unit of work to be run, usually on a queue. You generate one with ",[15,38451,38452],{},"php artisan make:job",", and put the task logic in its ",[15,38455,32113],{}," method.",[83,38458,38460],{"className":85,"code":38459,"language":87,"meta":88,"style":88},"class ProcessPodcast implements ShouldQueue\n{\n    public function __construct(public Podcast $podcast) {}\n\n    public function handle(): void\n    {\n        // heavy processing here\n    }\n}\n\n// Dispatch it onto the queue\nProcessPodcast::dispatch($podcast);\n",[15,38461,38462,38473,38477,38495,38499,38513,38517,38522,38526,38530,38534,38539],{"__ignoreMap":88},[92,38463,38464,38466,38469,38471],{"class":94,"line":95},[92,38465,6122],{"class":98},[92,38467,38468],{"class":5161}," ProcessPodcast",[92,38470,7522],{"class":98},[92,38472,11207],{"class":5161},[92,38474,38475],{"class":94,"line":106},[92,38476,11212],{"class":119},[92,38478,38479,38481,38483,38485,38487,38489,38492],{"class":94,"line":113},[92,38480,6132],{"class":98},[92,38482,5659],{"class":98},[92,38484,6163],{"class":102},[92,38486,120],{"class":119},[92,38488,6327],{"class":98},[92,38490,38491],{"class":102}," Podcast",[92,38493,38494],{"class":119}," $podcast) {}\n",[92,38496,38497],{"class":94,"line":138},[92,38498,110],{"emptyLinePlaceholder":109},[92,38500,38501,38503,38505,38507,38509,38511],{"class":94,"line":143},[92,38502,6132],{"class":98},[92,38504,5659],{"class":98},[92,38506,11255],{"class":5161},[92,38508,6042],{"class":119},[92,38510,5185],{"class":98},[92,38512,11262],{"class":98},[92,38514,38515],{"class":94,"line":149},[92,38516,11267],{"class":119},[92,38518,38519],{"class":94,"line":155},[92,38520,38521],{"class":134},"        // heavy processing here\n",[92,38523,38524],{"class":94,"line":161},[92,38525,5104],{"class":119},[92,38527,38528],{"class":94,"line":166},[92,38529,4711],{"class":119},[92,38531,38532],{"class":94,"line":187},[92,38533,110],{"emptyLinePlaceholder":109},[92,38535,38536],{"class":94,"line":217},[92,38537,38538],{"class":134},"// Dispatch it onto the queue\n",[92,38540,38541,38544,38546,38548],{"class":94,"line":712},[92,38542,38543],{"class":102},"ProcessPodcast",[92,38545,6818],{"class":98},[92,38547,11722],{"class":5161},[92,38549,38550],{"class":119},"($podcast);\n",[11,38552,38553,38554,38557,38558,38561],{},"Implementing the ",[15,38555,38556],{},"ShouldQueue"," interface tells Laravel to run the job in the background rather than immediately. You can also delay it (",[15,38559,38560],{},"->delay(now()->addMinutes(5))",") or send it to a specific queue. Dispatching is how you hand work off to be processed later by a worker.",[242,38563,38565,38566,834,38569,897],{"id":38564},"_79-what-is-the-difference-between-queuework-and-queuelisten","79. What is the difference between ",[15,38567,38568],{},"queue:work",[15,38570,38571],{},"queue:listen",[11,38573,38574],{},"Both are commands that start a worker to process queued jobs, but they behave differently regarding code changes.",[11,38576,38577,38579,38580,38583,38584,38586],{},[15,38578,38568],{}," starts a ",[10490,38581,38582],{},"long-running"," process that boots the framework once and keeps it in memory to process jobs quickly. Because it holds the code in memory, it does ",[10490,38585,5608],{}," pick up code changes until you restart it, which makes it efficient and the right choice for production (usually managed by a process supervisor).",[11,38588,38589,38591,38592,38595],{},[15,38590,38571],{}," boots the framework ",[10490,38593,38594],{},"fresh for every job",", so it automatically uses your latest code without a restart. That's convenient during development but much slower and heavier.",[11,38597,37123,38598,38600,38601,38604,38605,38607],{},[15,38599,38568],{}," in production for performance (and remember to restart it on deploy with ",[15,38602,38603],{},"queue:restart","), and ",[15,38606,38571],{}," only when you're actively developing and want changes picked up immediately.",[242,38609,38611],{"id":38610},"_80-how-does-laravel-handle-failed-jobs-and-retries","80. How does Laravel handle failed jobs and retries?",[11,38613,38614,38615,38618,38619,38622,38623,38626],{},"When a queued job throws an exception, Laravel can automatically ",[10490,38616,38617],{},"retry"," it a set number of times before giving up. You control this with the ",[15,38620,38621],{},"--tries"," option on the worker (or a ",[15,38624,38625],{},"$tries"," property on the job).",[83,38628,38630],{"className":11136,"code":38629,"language":11138,"meta":88,"style":88},"php artisan queue:work --tries=3 --backoff=10\n",[15,38631,38632],{"__ignoreMap":88},[92,38633,38634,38636,38639,38642,38645],{"class":94,"line":95},[92,38635,87],{"class":5161},[92,38637,38638],{"class":171}," artisan",[92,38640,38641],{"class":171}," queue:work",[92,38643,38644],{"class":102}," --tries=3",[92,38646,38647],{"class":102}," --backoff=10\n",[11,38649,38650,38653,38654,38657,38658,38661,38662,38665],{},[15,38651,38652],{},"--backoff"," adds a delay between retries (useful when waiting for a flaky service to recover). Once a job has exhausted its attempts, it's recorded in the ",[15,38655,38656],{},"failed_jobs"," table so it isn't lost. You can then inspect failures, retry them with ",[15,38659,38660],{},"php artisan queue:retry",", and define a ",[15,38663,38664],{},"failed()"," method on the job to run cleanup or alerting when it ultimately fails. This makes background processing resilient rather than silently losing work.",[242,38667,38669,38670,38672],{"id":38668},"_81-what-is-the-sync-queue-driver-and-when-is-it-used","81. What is the ",[15,38671,29559],{}," queue driver, and when is it used?",[11,38674,1792,38675,38677,38678,38681],{},[15,38676,29559],{}," driver is a special \"queue\" that doesn't actually queue anything; it runs jobs ",[10490,38679,38680],{},"immediately and synchronously",", in the same request that dispatched them.",[11,38683,38684,38685,38688],{},"It's the default in local development because it means you don't need to run a separate worker or set up Redis just to test that dispatching works. Your ",[15,38686,38687],{},"ProcessPodcast::dispatch()"," call simply executes right away.",[11,38690,38691,38692,38694,38695,38698,38699,38702,38703,6339,38706,38709],{},"The catch is that with ",[15,38693,29559],{},", background jobs no longer happen in the background; the user ",[1511,38696,38697],{},"does"," wait for them. So it's purely for convenience during development or simple testing. In production you switch ",[15,38700,38701],{},"QUEUE_CONNECTION"," to a real driver like ",[15,38704,38705],{},"redis",[15,38707,38708],{},"database"," so jobs actually run asynchronously.",[242,38711,38713],{"id":38712},"_82-what-is-job-batching-and-job-chaining","82. What is job batching and job chaining?",[11,38715,38716],{},"Both coordinate multiple jobs, but in different shapes.",[11,38718,38719,38722,38723,38726],{},[10490,38720,38721],{},"Job chaining"," runs jobs in a ",[10490,38724,38725],{},"sequence",", where each one runs only after the previous succeeds. If any job in the chain fails, the rest don't run.",[83,38728,38730],{"className":85,"code":38729,"language":87,"meta":88,"style":88},"Bus::chain([\n    new ProcessPayment,\n    new SendReceipt,\n    new UpdateInventory,\n])->dispatch();\n",[15,38731,38732,38744,38754,38763,38772],{"__ignoreMap":88},[92,38733,38734,38737,38739,38742],{"class":94,"line":95},[92,38735,38736],{"class":102},"Bus",[92,38738,6818],{"class":98},[92,38740,38741],{"class":5161},"chain",[92,38743,33466],{"class":119},[92,38745,38746,38749,38752],{"class":94,"line":106},[92,38747,38748],{"class":98},"    new",[92,38750,38751],{"class":102}," ProcessPayment",[92,38753,4772],{"class":119},[92,38755,38756,38758,38761],{"class":94,"line":113},[92,38757,38748],{"class":98},[92,38759,38760],{"class":102}," SendReceipt",[92,38762,4772],{"class":119},[92,38764,38765,38767,38770],{"class":94,"line":138},[92,38766,38748],{"class":98},[92,38768,38769],{"class":102}," UpdateInventory",[92,38771,4772],{"class":119},[92,38773,38774,38776,38778,38780],{"class":94,"line":143},[92,38775,32402],{"class":119},[92,38777,1996],{"class":98},[92,38779,11722],{"class":5161},[92,38781,7730],{"class":119},[11,38783,38784,38787],{},[10490,38785,38786],{},"Job batching"," runs a group of jobs (often in parallel) and lets you track their collective progress, with a callback that fires when they all finish.",[83,38789,38791],{"className":85,"code":38790,"language":87,"meta":88,"style":88},"Bus::batch([\n    new ImportUsers(1),\n    new ImportUsers(2),\n])->then(fn () => Log::info('All done'))->dispatch();\n",[15,38792,38793,38804,38818,38830],{"__ignoreMap":88},[92,38794,38795,38797,38799,38802],{"class":94,"line":95},[92,38796,38736],{"class":102},[92,38798,6818],{"class":98},[92,38800,38801],{"class":5161},"batch",[92,38803,33466],{"class":119},[92,38805,38806,38808,38811,38813,38815],{"class":94,"line":106},[92,38807,38748],{"class":98},[92,38809,38810],{"class":102}," ImportUsers",[92,38812,120],{"class":119},[92,38814,68],{"class":102},[92,38816,38817],{"class":119},"),\n",[92,38819,38820,38822,38824,38826,38828],{"class":94,"line":113},[92,38821,38748],{"class":98},[92,38823,38810],{"class":102},[92,38825,120],{"class":119},[92,38827,354],{"class":102},[92,38829,38817],{"class":119},[92,38831,38832,38834,38836,38839,38841,38843,38845,38848,38850,38852,38854,38857,38859,38861,38863],{"class":94,"line":138},[92,38833,32402],{"class":119},[92,38835,1996],{"class":98},[92,38837,38838],{"class":5161},"then",[92,38840,120],{"class":119},[92,38842,3466],{"class":98},[92,38844,11482],{"class":119},[92,38846,38847],{"class":102},"Log",[92,38849,6818],{"class":98},[92,38851,11277],{"class":5161},[92,38853,120],{"class":119},[92,38855,38856],{"class":171},"'All done'",[92,38858,7171],{"class":119},[92,38860,1996],{"class":98},[92,38862,11722],{"class":5161},[92,38864,7730],{"class":119},[11,38866,36535,38867,38870,38871,38874],{},[10490,38868,38869],{},"chaining"," when steps must happen in order, and ",[10490,38872,38873],{},"batching"," when many independent jobs should run together and you want to know when the whole set completes (like processing a large CSV in chunks).",[242,38876,38878],{"id":38877},"_83-what-is-task-scheduling-and-how-does-the-scheduler-work","83. What is task scheduling, and how does the scheduler work?",[11,38880,38881,38884],{},[10490,38882,38883],{},"Task scheduling"," lets you run commands or code on a recurring schedule (hourly, daily, weekly) defined in code, instead of manually editing server cron files for each task.",[11,38886,38887,38888,38891],{},"You define the schedule in your app (in ",[15,38889,38890],{},"routes/console.php"," or the console kernel):",[83,38893,38895],{"className":85,"code":38894,"language":87,"meta":88,"style":88},"Schedule::command('reports:send')->daily();\nSchedule::job(new PruneOldRecords)->weekly();\n",[15,38896,38897,38919],{"__ignoreMap":88},[92,38898,38899,38901,38903,38905,38907,38910,38912,38914,38917],{"class":94,"line":95},[92,38900,11429],{"class":102},[92,38902,6818],{"class":98},[92,38904,11434],{"class":5161},[92,38906,120],{"class":119},[92,38908,38909],{"class":171},"'reports:send'",[92,38911,5182],{"class":119},[92,38913,1996],{"class":98},[92,38915,38916],{"class":5161},"daily",[92,38918,7730],{"class":119},[92,38920,38921,38923,38925,38928,38930,38932,38935,38937,38939,38942],{"class":94,"line":106},[92,38922,11429],{"class":102},[92,38924,6818],{"class":98},[92,38926,38927],{"class":5161},"job",[92,38929,120],{"class":119},[92,38931,3334],{"class":98},[92,38933,38934],{"class":102}," PruneOldRecords",[92,38936,5182],{"class":119},[92,38938,1996],{"class":98},[92,38940,38941],{"class":5161},"weekly",[92,38943,7730],{"class":119},[11,38945,38946,38947,38950,38951,38954],{},"The clever part: you add ",[10490,38948,38949],{},"one"," cron entry on the server that runs ",[15,38952,38953],{},"php artisan schedule:run"," every minute. Laravel checks which of your scheduled tasks are due at that moment and runs them. So you manage all scheduled tasks in readable PHP code, version-controlled with the rest of your app, instead of a tangle of raw crontab lines.",[39,38956,38958],{"id":38957},"caching-sessions-and-config","Caching, Sessions, and Config",[242,38960,38962],{"id":38961},"_84-how-does-caching-work-in-laravel-and-what-drivers-are-available","84. How does caching work in Laravel, and what drivers are available?",[11,38964,38965,38968],{},[10490,38966,38967],{},"Caching"," stores the result of an expensive operation (a slow query, an API call, a computed value) so future requests can reuse it instead of recomputing, which speeds up your app.",[11,38970,38971,38972,38974,38975,195,38977,195,38980,195,38982,394,38984,38986],{},"Laravel offers a unified ",[15,38973,31754],{}," API that works the same regardless of the underlying store, so you can swap backends without changing code. Supported drivers include ",[15,38976,38705],{},[15,38978,38979],{},"memcached",[15,38981,38708],{},[15,38983,11689],{},[15,38985,383],{}," (for testing).",[83,38988,38990],{"className":85,"code":38989,"language":87,"meta":88,"style":88},"Cache::put('key', $value, now()->addMinutes(10)); // store for 10 minutes\n$value = Cache::get('key');                        // retrieve\nCache::forget('key');                              // remove\n",[15,38991,38992,39025,39048],{"__ignoreMap":88},[92,38993,38994,38996,38998,39000,39002,39004,39007,39009,39011,39013,39016,39018,39020,39022],{"class":94,"line":95},[92,38995,31754],{"class":102},[92,38997,6818],{"class":98},[92,38999,11579],{"class":5161},[92,39001,120],{"class":119},[92,39003,12952],{"class":171},[92,39005,39006],{"class":119},", $value, ",[92,39008,11589],{"class":5161},[92,39010,6042],{"class":119},[92,39012,1996],{"class":98},[92,39014,39015],{"class":5161},"addMinutes",[92,39017,120],{"class":119},[92,39019,4419],{"class":102},[92,39021,3520],{"class":119},[92,39023,39024],{"class":134},"// store for 10 minutes\n",[92,39026,39027,39030,39032,39034,39036,39038,39040,39042,39045],{"class":94,"line":106},[92,39028,39029],{"class":119},"$value ",[92,39031,126],{"class":98},[92,39033,11550],{"class":102},[92,39035,6818],{"class":98},[92,39037,8985],{"class":5161},[92,39039,120],{"class":119},[92,39041,12952],{"class":171},[92,39043,39044],{"class":119},");                        ",[92,39046,39047],{"class":134},"// retrieve\n",[92,39049,39050,39052,39054,39057,39059,39061,39064],{"class":94,"line":113},[92,39051,31754],{"class":102},[92,39053,6818],{"class":98},[92,39055,39056],{"class":5161},"forget",[92,39058,120],{"class":119},[92,39060,12952],{"class":171},[92,39062,39063],{"class":119},");                              ",[92,39065,39066],{"class":134},"// remove\n",[11,39068,39069,39070,834,39072,39074],{},"For real applications you'd typically use Redis or Memcached, which keep data in memory for very fast access. The ",[15,39071,11689],{},[15,39073,38708],{}," drivers work without extra infrastructure and are fine for smaller apps.",[242,39076,39078,39079,32126],{"id":39077},"_85-what-does-cacheremember-do","85. What does ",[15,39080,39081],{},"Cache::remember()",[11,39083,39084,39086],{},[15,39085,39081],{}," is a convenient method that combines \"check the cache, and if it's missing, compute the value and store it,\" all in one call. It's the most common caching pattern (cache-aside) expressed cleanly.",[83,39088,39090],{"className":85,"code":39089,"language":87,"meta":88,"style":88},"$users = Cache::remember('active_users', 600, function () {\n    return User::where('active', true)->get();\n});\n",[15,39091,39092,39121,39147],{"__ignoreMap":88},[92,39093,39094,39096,39098,39100,39102,39105,39107,39110,39112,39115,39117,39119],{"class":94,"line":95},[92,39095,34096],{"class":119},[92,39097,126],{"class":98},[92,39099,11550],{"class":102},[92,39101,6818],{"class":98},[92,39103,39104],{"class":5161},"remember",[92,39106,120],{"class":119},[92,39108,39109],{"class":171},"'active_users'",[92,39111,195],{"class":119},[92,39113,39114],{"class":102},"600",[92,39116,195],{"class":119},[92,39118,3556],{"class":98},[92,39120,32636],{"class":119},[92,39122,39123,39125,39127,39129,39131,39133,39135,39137,39139,39141,39143,39145],{"class":94,"line":106},[92,39124,5195],{"class":98},[92,39126,8699],{"class":102},[92,39128,6818],{"class":98},[92,39130,34105],{"class":5161},[92,39132,120],{"class":119},[92,39134,34110],{"class":171},[92,39136,195],{"class":119},[92,39138,474],{"class":102},[92,39140,5182],{"class":119},[92,39142,1996],{"class":98},[92,39144,8985],{"class":5161},[92,39146,7730],{"class":119},[92,39148,39149],{"class":94,"line":113},[92,39150,11624],{"class":119},[11,39152,39153,39154,39157,39158,39161],{},"Here Laravel first checks for ",[15,39155,39156],{},"active_users"," in the cache. If it's there, it returns it immediately. If not, it runs the closure (the expensive query), stores the result for 600 seconds, and returns it. This saves you from writing the manual \"if cached return it, else fetch and cache\" logic every time. There's also ",[15,39159,39160],{},"rememberForever()"," for values that don't expire.",[242,39163,39165],{"id":39164},"_86-how-does-session-management-work-and-what-session-drivers-exist","86. How does session management work, and what session drivers exist?",[11,39167,6686,39168,39170],{},[10490,39169,11572],{}," stores information about a user across multiple requests (since HTTP itself is stateless), like keeping them logged in or holding flash messages. Laravel manages this for you and gives a simple API.",[83,39172,39174],{"className":85,"code":39173,"language":87,"meta":88,"style":88},"session(['cart_id' => 42]);   // store\n$id = session('cart_id');     // retrieve\nsession()->forget('cart_id'); // remove\n",[15,39175,39176,39194,39212],{"__ignoreMap":88},[92,39177,39178,39180,39182,39185,39187,39189,39191],{"class":94,"line":95},[92,39179,11572],{"class":5161},[92,39181,486],{"class":119},[92,39183,39184],{"class":171},"'cart_id'",[92,39186,1019],{"class":98},[92,39188,283],{"class":102},[92,39190,5873],{"class":119},[92,39192,39193],{"class":134},"// store\n",[92,39195,39196,39199,39201,39204,39206,39208,39210],{"class":94,"line":106},[92,39197,39198],{"class":119},"$id ",[92,39200,126],{"class":98},[92,39202,39203],{"class":5161}," session",[92,39205,120],{"class":119},[92,39207,39184],{"class":171},[92,39209,599],{"class":119},[92,39211,39047],{"class":134},[92,39213,39214,39216,39218,39220,39222,39224,39226,39228],{"class":94,"line":113},[92,39215,11572],{"class":5161},[92,39217,6042],{"class":119},[92,39219,1996],{"class":98},[92,39221,39056],{"class":5161},[92,39223,120],{"class":119},[92,39225,39184],{"class":171},[92,39227,653],{"class":119},[92,39229,39066],{"class":134},[11,39231,39232,39233,39236,39237,5263,39240,39242,39243,195,39246,195,39248,1375,39250,39252,39253,39255,39256,6339,39258,39260,39261,39264,39265,81],{},"Where the session data actually lives depends on the ",[10490,39234,39235],{},"driver",", configured in ",[15,39238,39239],{},"config/session.php",[15,39241,11689],{}," (the default, stored on disk), ",[15,39244,39245],{},"cookie",[15,39247,38708],{},[15,39249,38705],{},[15,39251,38979],{},". For a single server the ",[15,39254,11689],{}," driver is fine, but once you scale to multiple servers behind a load balancer you'd use ",[15,39257,38705],{},[15,39259,38708],{}," so the session is shared and any server can read it. For how the session cookie itself compares to other browser storage options like ",[15,39262,39263],{},"localStorage",", see ",[23,39266,39268],{"href":39267},"/post/local-storage-vs-session-storage-vs-cookies","Local Storage vs Session Storage vs Cookies",[242,39270,39272,39273,897],{"id":39271},"_87-how-does-config-caching-affect-the-use-of-env","87. How does config caching affect the use of ",[15,39274,13914],{},[11,39276,39277,39278,39280,39281,39287,39288,31948,39290,39292,39293,39295,39296,39298],{},"When you run ",[15,39279,31937],{},", Laravel compiles all your config files into a single cached file for speed, and from then on it ",[10490,39282,39283,39284,39286],{},"no longer reads the ",[15,39285,13905],{}," file"," on each request. This is great for production performance, but it has an important consequence: any ",[15,39289,13914],{},[1511,39291,31951],{}," the ",[15,39294,31895],{}," directory will return ",[15,39297,390],{},", because the environment isn't being loaded anymore.",[11,39300,39301,39302,39304,39305,39307,39308,39310,39311,81],{},"This is exactly why the best practice is to only call ",[15,39303,13914],{}," inside config files, and everywhere else use ",[15,39306,31911],{},". If you follow that rule, config caching is a free performance win. If you sprinkle ",[15,39309,13914],{}," throughout your code and then cache config in production, you'll get confusing bugs where values suddenly become ",[15,39312,390],{},[39,39314,39316],{"id":39315},"collections-and-helpers","Collections and Helpers",[242,39318,39320],{"id":39319},"_88-what-are-laravel-collections-and-how-do-they-differ-from-plain-arrays","88. What are Laravel Collections, and how do they differ from plain arrays?",[11,39322,6686,39323,39326,39327,39330],{},[10490,39324,39325],{},"Collection"," is a wrapper around an array that provides a fluent, chainable set of methods for working with data. Eloquent queries return collections, and you can wrap any array with the ",[15,39328,39329],{},"collect()"," helper.",[11,39332,39333],{},"The advantage over a plain array is readability and expressiveness. Compare filtering and transforming with a collection versus nested PHP array functions:",[83,39335,39337],{"className":85,"code":39336,"language":87,"meta":88,"style":88},"$names = collect($users)\n    ->filter(fn ($u) => $u->active)\n    ->map(fn ($u) => $u->name)\n    ->values();\n",[15,39338,39339,39352,39371,39388],{"__ignoreMap":88},[92,39340,39341,39344,39346,39349],{"class":94,"line":95},[92,39342,39343],{"class":119},"$names ",[92,39345,126],{"class":98},[92,39347,39348],{"class":5161}," collect",[92,39350,39351],{"class":119},"($users)\n",[92,39353,39354,39356,39359,39361,39363,39366,39368],{"class":94,"line":106},[92,39355,32600],{"class":98},[92,39357,39358],{"class":5161},"filter",[92,39360,120],{"class":119},[92,39362,3466],{"class":98},[92,39364,39365],{"class":119}," ($u) => $u",[92,39367,1996],{"class":98},[92,39369,39370],{"class":119},"active)\n",[92,39372,39373,39375,39377,39379,39381,39383,39385],{"class":94,"line":113},[92,39374,32600],{"class":98},[92,39376,26597],{"class":5161},[92,39378,120],{"class":119},[92,39380,3466],{"class":98},[92,39382,39365],{"class":119},[92,39384,1996],{"class":98},[92,39386,39387],{"class":119},"name)\n",[92,39389,39390,39392,39395],{"class":94,"line":138},[92,39391,32600],{"class":98},[92,39393,39394],{"class":5161},"values",[92,39396,7730],{"class":119},[11,39398,39399,39400,195,39402,195,39404,195,39407,195,39409,195,39412,195,39415,39417,39418,39425],{},"Collections offer dozens of helpful methods (",[15,39401,26597],{},[15,39403,39358],{},[15,39405,39406],{},"reduce",[15,39408,36502],{},[15,39410,39411],{},"groupBy",[15,39413,39414],{},"sortBy",[15,39416,5394],{},"), all chainable, which makes data manipulation far cleaner than juggling the raw ",[23,39419,39420,195,39422,39424],{"href":15354},[15,39421,3322],{},[15,39423,3326],{},", and friends"," directly. Under the hood it's still an array, but the API is much nicer to work with.",[242,39427,39429,39430,195,39433,195,39436,394,39439,39442],{"id":39428},"_89-what-is-the-difference-between-map-filter-reduce-and-each-on-a-collection","89. What is the difference between ",[15,39431,39432],{},"map()",[15,39434,39435],{},"filter()",[15,39437,39438],{},"reduce()",[15,39440,39441],{},"each()"," on a collection?",[11,39444,39445],{},"These are four common collection methods, each with a distinct purpose:",[11016,39447,39448,39456,39464,39472],{},[11019,39449,39450,1644,39452,39455],{},[15,39451,39432],{},[10490,39453,39454],{},"transforms"," each item and returns a new collection of the same size.",[11019,39457,39458,1644,39460,39463],{},[15,39459,39435],{},[10490,39461,39462],{},"keeps only"," items that pass a truth test, returning a smaller collection.",[11019,39465,39466,1644,39468,39471],{},[15,39467,39438],{},[10490,39469,39470],{},"boils the whole collection down"," to a single value (like a total).",[11019,39473,39474,39476,39477,39480],{},[15,39475,39441],{}," simply ",[10490,39478,39479],{},"loops"," over items to perform a side effect, without building a new collection.",[83,39482,39484],{"className":85,"code":39483,"language":87,"meta":88,"style":88},"$c = collect([1, 2, 3, 4]);\n\n$c->map(fn ($n) => $n * 2);           // [2, 4, 6, 8]\n$c->filter(fn ($n) => $n % 2 === 0);  // [2, 4]\n$c->reduce(fn ($carry, $n) => $carry + $n, 0); // 10\n$c->each(fn ($n) => Log::info($n));   // just iterates\n",[15,39485,39486,39512,39516,39541,39568,39593],{"__ignoreMap":88},[92,39487,39488,39490,39492,39494,39496,39498,39500,39502,39504,39506,39508,39510],{"class":94,"line":95},[92,39489,8529],{"class":119},[92,39491,126],{"class":98},[92,39493,39348],{"class":5161},[92,39495,486],{"class":119},[92,39497,68],{"class":102},[92,39499,195],{"class":119},[92,39501,354],{"class":102},[92,39503,195],{"class":119},[92,39505,1448],{"class":102},[92,39507,195],{"class":119},[92,39509,3621],{"class":102},[92,39511,11674],{"class":119},[92,39513,39514],{"class":94,"line":106},[92,39515,110],{"emptyLinePlaceholder":109},[92,39517,39518,39521,39523,39525,39527,39529,39532,39534,39536,39538],{"class":94,"line":113},[92,39519,39520],{"class":119},"$c",[92,39522,1996],{"class":98},[92,39524,26597],{"class":5161},[92,39526,120],{"class":119},[92,39528,3466],{"class":98},[92,39530,39531],{"class":119}," ($n) => $n ",[92,39533,1959],{"class":98},[92,39535,1225],{"class":102},[92,39537,2378],{"class":119},[92,39539,39540],{"class":134},"// [2, 4, 6, 8]\n",[92,39542,39543,39545,39547,39549,39551,39553,39555,39557,39559,39561,39563,39565],{"class":94,"line":138},[92,39544,39520],{"class":119},[92,39546,1996],{"class":98},[92,39548,39358],{"class":5161},[92,39550,120],{"class":119},[92,39552,3466],{"class":98},[92,39554,39531],{"class":119},[92,39556,1178],{"class":98},[92,39558,1225],{"class":102},[92,39560,1405],{"class":98},[92,39562,331],{"class":102},[92,39564,800],{"class":119},[92,39566,39567],{"class":134},"// [2, 4]\n",[92,39569,39570,39572,39574,39576,39578,39580,39583,39585,39587,39589,39591],{"class":94,"line":143},[92,39571,39520],{"class":119},[92,39573,1996],{"class":98},[92,39575,39406],{"class":5161},[92,39577,120],{"class":119},[92,39579,3466],{"class":98},[92,39581,39582],{"class":119}," ($carry, $n) => $carry ",[92,39584,1795],{"class":98},[92,39586,3539],{"class":119},[92,39588,554],{"class":102},[92,39590,653],{"class":119},[92,39592,1215],{"class":134},[92,39594,39595,39597,39599,39602,39604,39606,39609,39611,39613,39615,39618],{"class":94,"line":149},[92,39596,39520],{"class":119},[92,39598,1996],{"class":98},[92,39600,39601],{"class":5161},"each",[92,39603,120],{"class":119},[92,39605,3466],{"class":98},[92,39607,39608],{"class":119}," ($n) => ",[92,39610,38847],{"class":102},[92,39612,6818],{"class":98},[92,39614,11277],{"class":5161},[92,39616,39617],{"class":119},"($n));   ",[92,39619,39620],{"class":134},"// just iterates\n",[11,39622,39623,39624,834,39626,39628,39629,39631,39632,39634],{},"The key distinction: ",[15,39625,26597],{},[15,39627,39358],{}," return new collections (so they're chainable and don't mutate the original), ",[15,39630,39406],{}," returns one aggregated value, and ",[15,39633,39601],{}," is for side effects only.",[242,39636,39638],{"id":39637},"_90-what-is-the-difference-between-a-collection-and-a-lazycollection","90. What is the difference between a Collection and a LazyCollection?",[11,39640,39641,39642,39644,39645,39647,39648,39651],{},"A regular ",[10490,39643,39325],{}," loads all its items into memory at once. A ",[10490,39646,36259],{}," uses PHP generators to process items ",[10490,39649,39650],{},"one at a time",", only pulling the next item when needed, which keeps memory usage low for huge datasets.",[11,39653,39654],{},"The difference matters when you're dealing with something too big to fit in memory, like reading a massive file or streaming millions of database rows.",[83,39656,39658],{"className":85,"code":39657,"language":87,"meta":88,"style":88},"LazyCollection::make(function () {\n    $handle = fopen('huge.csv', 'r');\n    while (($line = fgets($handle)) !== false) {\n        yield $line;\n    }\n})->each(fn ($line) => /* process one line */);\n",[15,39659,39660,39674,39696,39718,39725,39729],{"__ignoreMap":88},[92,39661,39662,39664,39666,39668,39670,39672],{"class":94,"line":95},[92,39663,36259],{"class":102},[92,39665,6818],{"class":98},[92,39667,26148],{"class":5161},[92,39669,120],{"class":119},[92,39671,3556],{"class":98},[92,39673,32636],{"class":119},[92,39675,39676,39679,39681,39684,39686,39689,39691,39694],{"class":94,"line":106},[92,39677,39678],{"class":119},"    $handle ",[92,39680,126],{"class":98},[92,39682,39683],{"class":102}," fopen",[92,39685,120],{"class":119},[92,39687,39688],{"class":171},"'huge.csv'",[92,39690,195],{"class":119},[92,39692,39693],{"class":171},"'r'",[92,39695,6289],{"class":119},[92,39697,39698,39701,39704,39706,39709,39712,39714,39716],{"class":94,"line":113},[92,39699,39700],{"class":98},"    while",[92,39702,39703],{"class":119}," (($line ",[92,39705,126],{"class":98},[92,39707,39708],{"class":102}," fgets",[92,39710,39711],{"class":119},"($handle)) ",[92,39713,1364],{"class":98},[92,39715,1546],{"class":102},[92,39717,4647],{"class":119},[92,39719,39720,39722],{"class":94,"line":138},[92,39721,5986],{"class":98},[92,39723,39724],{"class":119}," $line;\n",[92,39726,39727],{"class":94,"line":143},[92,39728,5104],{"class":119},[92,39730,39731,39734,39736,39738,39740,39742,39745,39748],{"class":94,"line":149},[92,39732,39733],{"class":119},"})",[92,39735,1996],{"class":98},[92,39737,39601],{"class":5161},[92,39739,120],{"class":119},[92,39741,3466],{"class":98},[92,39743,39744],{"class":119}," ($line) => ",[92,39746,39747],{"class":134},"/* process one line */",[92,39749,6289],{"class":119},[11,39751,39752,39753,39755],{},"You get the same friendly collection methods, but items flow through lazily instead of all being held at once. Eloquent's ",[15,39754,36245],{}," returns a LazyCollection for exactly this reason. Use a normal Collection for typical sized data, and a LazyCollection when memory would otherwise be a problem.",[242,39757,39759],{"id":39758},"_91-what-are-helper-functions-in-laravel-give-some-common-ones","91. What are helper functions in Laravel? Give some common ones.",[11,39761,39762,39765],{},[10490,39763,39764],{},"Helpers"," are globally available functions that provide handy shortcuts for common tasks, so you don't have to reach for a class or facade for small things. They cover strings, arrays, paths, URLs, and more.",[11,39767,39768],{},"Some you'll use constantly:",[11016,39770,39771,39781,39790,39800,39810],{},[11019,39772,39773,39776,39777,39780],{},[15,39774,39775],{},"route('name')"," generates a URL for a named route, ",[15,39778,39779],{},"url('/path')"," for any URL.",[11019,39782,39783,39786,39787,39789],{},[15,39784,39785],{},"config('app.name')"," reads a config value, ",[15,39788,37568],{}," gets the current user.",[11019,39791,39792,39795,39796,39799],{},[15,39793,39794],{},"collect([...])"," wraps an array in a collection, ",[15,39797,39798],{},"now()"," gives the current time as a Carbon instance.",[11019,39801,39802,39805,39806,39809],{},[15,39803,39804],{},"old('field')"," retrieves old input in forms, ",[15,39807,39808],{},"abort(404)"," throws an HTTP error.",[11019,39811,39812,39815],{},[15,39813,39814],{},"dd($var)"," dumps a value and stops execution for debugging.",[11,39817,39818,39819,195,39822,39825],{},"They keep everyday code concise and readable. There are also string and array helper classes (",[15,39820,39821],{},"Str::slug()",[15,39823,39824],{},"Arr::get()",") for more specialized work.",[39,39827,39829],{"id":39828},"apis-and-resources","APIs and Resources",[242,39831,39833],{"id":39832},"_92-how-do-you-build-a-json-api-in-laravel","92. How do you build a JSON API in Laravel?",[11,39835,39836,39837,39839,39840,39842],{},"To build an API you define routes in ",[15,39838,32351],{}," (automatically prefixed with ",[15,39841,32355],{}," and stateless), point them at controllers, and return data that Laravel serializes to JSON.",[83,39844,39846],{"className":85,"code":39845,"language":87,"meta":88,"style":88},"// routes/api.php\nRoute::get('/posts', [PostController::class, 'index']);\n\n// Controller\npublic function index()\n{\n    return Post::all(); // automatically returned as JSON\n}\n",[15,39847,39848,39853,39877,39881,39886,39897,39901,39916],{"__ignoreMap":88},[92,39849,39850],{"class":94,"line":95},[92,39851,39852],{"class":134},"// routes/api.php\n",[92,39854,39855,39857,39859,39861,39863,39865,39867,39869,39871,39873,39875],{"class":94,"line":106},[92,39856,11466],{"class":102},[92,39858,6818],{"class":98},[92,39860,8985],{"class":5161},[92,39862,120],{"class":119},[92,39864,32276],{"class":171},[92,39866,2708],{"class":119},[92,39868,32281],{"class":102},[92,39870,6985],{"class":98},[92,39872,195],{"class":119},[92,39874,32288],{"class":171},[92,39876,11674],{"class":119},[92,39878,39879],{"class":94,"line":113},[92,39880,110],{"emptyLinePlaceholder":109},[92,39882,39883],{"class":94,"line":138},[92,39884,39885],{"class":134},"// Controller\n",[92,39887,39888,39890,39892,39895],{"class":94,"line":143},[92,39889,6327],{"class":98},[92,39891,5659],{"class":98},[92,39893,39894],{"class":5161}," index",[92,39896,27470],{"class":119},[92,39898,39899],{"class":94,"line":149},[92,39900,11212],{"class":119},[92,39902,39903,39905,39907,39909,39911,39913],{"class":94,"line":155},[92,39904,5195],{"class":98},[92,39906,34304],{"class":102},[92,39908,6818],{"class":98},[92,39910,33765],{"class":5161},[92,39912,27477],{"class":119},[92,39914,39915],{"class":134},"// automatically returned as JSON\n",[92,39917,39918],{"class":94,"line":161},[92,39919,4711],{"class":119},[11,39921,39922,39923,39926,39927,39930],{},"Returning an Eloquent model or collection automatically produces a JSON response. For real APIs you'd typically add ",[10490,39924,39925],{},"API Resources"," to control the exact JSON shape, apply the ",[15,39928,39929],{},"auth:sanctum"," middleware for authentication, use throttling for rate limits, and validate input with Form Requests. Laravel gives you everything needed for a clean, well-structured API out of the box.",[242,39932,39934],{"id":39933},"_93-what-are-api-resources-eloquent-resources","93. What are API Resources (Eloquent Resources)?",[11,39936,39937,39939],{},[10490,39938,39925],{}," are classes that act as a transformation layer between your Eloquent models and the JSON your API returns. They let you control exactly which fields are exposed and how they're formatted, instead of dumping the raw model (which might leak internal columns).",[83,39941,39943],{"className":85,"code":39942,"language":87,"meta":88,"style":88},"class UserResource extends JsonResource\n{\n    public function toArray($request): array\n    {\n        return [\n            'id'    => $this->id,\n            'name'  => $this->name,\n            'email' => $this->email,\n            // note: no password, no internal flags\n        ];\n    }\n}\n\n// In a controller\nreturn UserResource::collection(User::all());\n",[15,39944,39945,39957,39961,39977,39981,39987,40001,40014,40027,40032,40036,40040,40044,40048,40053],{"__ignoreMap":88},[92,39946,39947,39949,39952,39954],{"class":94,"line":95},[92,39948,6122],{"class":98},[92,39950,39951],{"class":5161}," UserResource",[92,39953,7096],{"class":98},[92,39955,39956],{"class":5161}," JsonResource\n",[92,39958,39959],{"class":94,"line":106},[92,39960,11212],{"class":119},[92,39962,39963,39965,39967,39970,39973,39975],{"class":94,"line":113},[92,39964,6132],{"class":98},[92,39966,5659],{"class":98},[92,39968,39969],{"class":5161}," toArray",[92,39971,39972],{"class":119},"($request)",[92,39974,5185],{"class":98},[92,39976,33625],{"class":98},[92,39978,39979],{"class":94,"line":138},[92,39980,11267],{"class":119},[92,39982,39983,39985],{"class":94,"line":143},[92,39984,6236],{"class":98},[92,39986,3034],{"class":119},[92,39988,39989,39992,39994,39996,39998],{"class":94,"line":149},[92,39990,39991],{"class":171},"            'id'",[92,39993,34846],{"class":98},[92,39995,6239],{"class":102},[92,39997,1996],{"class":98},[92,39999,40000],{"class":119},"id,\n",[92,40002,40003,40005,40007,40009,40011],{"class":94,"line":155},[92,40004,36331],{"class":171},[92,40006,36334],{"class":98},[92,40008,6239],{"class":102},[92,40010,1996],{"class":98},[92,40012,40013],{"class":119},"name,\n",[92,40015,40016,40018,40020,40022,40024],{"class":94,"line":161},[92,40017,36351],{"class":171},[92,40019,1019],{"class":98},[92,40021,6239],{"class":102},[92,40023,1996],{"class":98},[92,40025,40026],{"class":119},"email,\n",[92,40028,40029],{"class":94,"line":166},[92,40030,40031],{"class":134},"            // note: no password, no internal flags\n",[92,40033,40034],{"class":94,"line":187},[92,40035,36376],{"class":119},[92,40037,40038],{"class":94,"line":217},[92,40039,5104],{"class":119},[92,40041,40042],{"class":94,"line":712},[92,40043,4711],{"class":119},[92,40045,40046],{"class":94,"line":730},[92,40047,110],{"emptyLinePlaceholder":109},[92,40049,40050],{"class":94,"line":747},[92,40051,40052],{"class":134},"// In a controller\n",[92,40054,40055,40057,40059,40061,40064,40066,40068,40070,40072],{"class":94,"line":763},[92,40056,27101],{"class":98},[92,40058,39951],{"class":102},[92,40060,6818],{"class":98},[92,40062,40063],{"class":5161},"collection",[92,40065,120],{"class":119},[92,40067,27917],{"class":102},[92,40069,6818],{"class":98},[92,40071,33765],{"class":5161},[92,40073,9268],{"class":119},[11,40075,40076],{},"Resources give you a clean, consistent API contract: you decide the field names, hide sensitive data, rename or nest fields, and include related data conditionally. They're the recommended way to shape API output, keeping your JSON stable even if your database columns change.",[242,40078,40080],{"id":40079},"_94-what-is-api-rate-limiting-and-how-do-you-apply-throttling","94. What is API rate limiting, and how do you apply throttling?",[11,40082,40083,40086,40087,40090],{},[10490,40084,40085],{},"Rate limiting"," restricts how many requests a client can make in a given time window, protecting your API from abuse and overload. Laravel provides the ",[15,40088,40089],{},"throttle"," middleware for this.",[83,40092,40094],{"className":85,"code":40093,"language":87,"meta":88,"style":88},"Route::middleware('throttle:60,1')->group(function () {\n    // max 60 requests per 1 minute per client\n});\n",[15,40095,40096,40121,40126],{"__ignoreMap":88},[92,40097,40098,40100,40102,40104,40106,40109,40111,40113,40115,40117,40119],{"class":94,"line":95},[92,40099,11466],{"class":102},[92,40101,6818],{"class":98},[92,40103,31476],{"class":5161},[92,40105,120],{"class":119},[92,40107,40108],{"class":171},"'throttle:60,1'",[92,40110,5182],{"class":119},[92,40112,1996],{"class":98},[92,40114,32629],{"class":5161},[92,40116,120],{"class":119},[92,40118,3556],{"class":98},[92,40120,32636],{"class":119},[92,40122,40123],{"class":94,"line":106},[92,40124,40125],{"class":134},"    // max 60 requests per 1 minute per client\n",[92,40127,40128],{"class":94,"line":113},[92,40129,11624],{"class":119},[11,40131,40132],{},"You can also define named rate limiters in code for more control, for example limiting by the user's ID (so authenticated users get a higher allowance) or returning a custom response when the limit is hit:",[83,40134,40136],{"className":85,"code":40135,"language":87,"meta":88,"style":88},"RateLimiter::for('api', function (Request $request) {\n    return Limit::perMinute(100)->by($request->user()?->id ?: $request->ip());\n});\n",[15,40137,40138,40162,40209],{"__ignoreMap":88},[92,40139,40140,40143,40145,40147,40149,40152,40154,40156,40158,40160],{"class":94,"line":95},[92,40141,40142],{"class":102},"RateLimiter",[92,40144,6818],{"class":98},[92,40146,4906],{"class":5161},[92,40148,120],{"class":119},[92,40150,40151],{"class":171},"'api'",[92,40153,195],{"class":119},[92,40155,3556],{"class":98},[92,40157,3559],{"class":119},[92,40159,11537],{"class":102},[92,40161,11540],{"class":119},[92,40163,40164,40166,40169,40171,40174,40176,40179,40181,40183,40186,40188,40190,40192,40194,40196,40198,40200,40202,40204,40207],{"class":94,"line":106},[92,40165,5195],{"class":98},[92,40167,40168],{"class":102}," Limit",[92,40170,6818],{"class":98},[92,40172,40173],{"class":5161},"perMinute",[92,40175,120],{"class":119},[92,40177,40178],{"class":102},"100",[92,40180,5182],{"class":119},[92,40182,1996],{"class":98},[92,40184,40185],{"class":5161},"by",[92,40187,31612],{"class":119},[92,40189,1996],{"class":98},[92,40191,33170],{"class":5161},[92,40193,6042],{"class":119},[92,40195,1659],{"class":98},[92,40197,7786],{"class":119},[92,40199,1713],{"class":98},[92,40201,11684],{"class":119},[92,40203,1996],{"class":98},[92,40205,40206],{"class":5161},"ip",[92,40208,9268],{"class":119},[92,40210,40211],{"class":94,"line":113},[92,40212,11624],{"class":119},[11,40214,40215,40216,40219],{},"When a client exceeds the limit, Laravel automatically returns a ",[15,40217,40218],{},"429 Too Many Requests"," response. This is standard practice for any public-facing API.",[242,40221,40223],{"id":40222},"_95-how-do-you-authenticate-an-api-with-sanctum-tokens","95. How do you authenticate an API with Sanctum tokens?",[11,40225,40226],{},"With Sanctum, a user generates a personal access token, and clients send it as a Bearer token on each request. The server validates it and identifies the user, all without sessions.",[11,40228,40229],{},"First, issue a token (for example, after the user logs in):",[83,40231,40233],{"className":85,"code":40232,"language":87,"meta":88,"style":88},"$token = $user->createToken('mobile')->plainTextToken;\n// return this token to the client\n",[15,40234,40235,40258],{"__ignoreMap":88},[92,40236,40237,40239,40241,40243,40245,40247,40249,40252,40254,40256],{"class":94,"line":95},[92,40238,37641],{"class":119},[92,40240,126],{"class":98},[92,40242,1772],{"class":119},[92,40244,1996],{"class":98},[92,40246,37650],{"class":5161},[92,40248,120],{"class":119},[92,40250,40251],{"class":171},"'mobile'",[92,40253,5182],{"class":119},[92,40255,1996],{"class":98},[92,40257,37662],{"class":119},[92,40259,40260],{"class":94,"line":106},[92,40261,40262],{"class":134},"// return this token to the client\n",[11,40264,40265,40266,40268],{},"The client then includes it in the ",[15,40267,37894],{}," header on every request:",[83,40270,40274],{"className":40271,"code":40273,"language":36619},[40272],"language-text","Authorization: Bearer 1|abcdef123456...\n",[15,40275,40273],{"__ignoreMap":88},[11,40277,40278,40279,40281,40282,40285,40286,40289],{},"You protect routes with the ",[15,40280,39929],{}," middleware, which verifies the token and makes ",[15,40283,40284],{},"$request->user()"," available. Tokens can be given ",[10490,40287,40288],{},"abilities"," (scopes) to limit what they can do, and revoked at any time. This is the standard way to secure a stateless API for mobile apps and third-party clients.",[242,40291,40293],{"id":40292},"_96-how-should-you-return-and-structure-error-responses-in-an-api","96. How should you return and structure error responses in an API?",[11,40295,40296,40297,40299,40300,40302,40303,40305,40306,81],{},"A good API returns errors as ",[10490,40298,9673],{}," with a meaningful HTTP status code and a clear message, so clients can handle them programmatically. Laravel does a lot of this automatically: failed validation returns a ",[15,40301,33517],{}," with the field errors, a missing model returns a ",[15,40304,32890],{},", and unauthenticated requests return a ",[15,40307,40308],{},"401",[83,40310,40312],{"className":14186,"code":40311,"language":9672,"meta":88,"style":88},"{\n    \"message\": \"The given data was invalid.\",\n    \"errors\": {\n        \"email\": [\"The email field is required.\"]\n    }\n}\n",[15,40313,40314,40318,40330,40338,40350,40354],{"__ignoreMap":88},[92,40315,40316],{"class":94,"line":95},[92,40317,11212],{"class":119},[92,40319,40320,40323,40325,40328],{"class":94,"line":106},[92,40321,40322],{"class":102},"    \"message\"",[92,40324,5263],{"class":119},[92,40326,40327],{"class":171},"\"The given data was invalid.\"",[92,40329,4772],{"class":119},[92,40331,40332,40335],{"class":94,"line":113},[92,40333,40334],{"class":102},"    \"errors\"",[92,40336,40337],{"class":119},": {\n",[92,40339,40340,40343,40345,40348],{"class":94,"line":138},[92,40341,40342],{"class":102},"        \"email\"",[92,40344,13093],{"class":119},[92,40346,40347],{"class":171},"\"The email field is required.\"",[92,40349,13109],{"class":119},[92,40351,40352],{"class":94,"line":143},[92,40353,5104],{"class":119},[92,40355,40356],{"class":94,"line":149},[92,40357,4711],{"class":119},[11,40359,40360],{},"For custom errors you control the shape and status:",[83,40362,40364],{"className":85,"code":40363,"language":87,"meta":88,"style":88},"return response()->json([\n    'message' => 'Order not found',\n], 404);\n",[15,40365,40366,40380,40392],{"__ignoreMap":88},[92,40367,40368,40370,40372,40374,40376,40378],{"class":94,"line":95},[92,40369,27101],{"class":98},[92,40371,11604],{"class":5161},[92,40373,6042],{"class":119},[92,40375,1996],{"class":98},[92,40377,9672],{"class":5161},[92,40379,33466],{"class":119},[92,40381,40382,40385,40387,40390],{"class":94,"line":106},[92,40383,40384],{"class":171},"    'message'",[92,40386,1019],{"class":98},[92,40388,40389],{"class":171}," 'Order not found'",[92,40391,4772],{"class":119},[92,40393,40394,40396,40398],{"class":94,"line":113},[92,40395,3711],{"class":119},[92,40397,32890],{"class":102},[92,40399,6289],{"class":119},[11,40401,40402],{},"The key is consistency: use appropriate status codes (Laravel's exception handler already maps common exceptions to the right ones), always return JSON for API routes rather than HTML error pages, and keep the error structure the same across your endpoints so clients can parse it reliably.",[39,40404,40406],{"id":40405},"file-storage-mail-notifications-and-more","File Storage, Mail, Notifications, and More",[242,40408,40410],{"id":40409},"_97-how-does-laravels-filesystemstorage-abstraction-work","97. How does Laravel's filesystem/storage abstraction work?",[11,40412,40413,40414,40417,40418,81],{},"Laravel's ",[10490,40415,40416],{},"filesystem"," gives you one consistent API for storing and reading files, whether they live on the local disk, on Amazon S3, or elsewhere. It's built on the Flysystem library, and you configure \"disks\" in ",[15,40419,12919],{},[83,40421,40423],{"className":85,"code":40422,"language":87,"meta":88,"style":88},"Storage::disk('public')->put('avatars/1.jpg', $contents);\n$url = Storage::disk('s3')->url('avatars/1.jpg');\nStorage::delete('old-file.txt');\n",[15,40424,40425,40453,40484],{"__ignoreMap":88},[92,40426,40427,40430,40432,40435,40437,40439,40441,40443,40445,40447,40450],{"class":94,"line":95},[92,40428,40429],{"class":102},"Storage",[92,40431,6818],{"class":98},[92,40433,40434],{"class":5161},"disk",[92,40436,120],{"class":119},[92,40438,33858],{"class":171},[92,40440,5182],{"class":119},[92,40442,1996],{"class":98},[92,40444,11579],{"class":5161},[92,40446,120],{"class":119},[92,40448,40449],{"class":171},"'avatars/1.jpg'",[92,40451,40452],{"class":119},", $contents);\n",[92,40454,40455,40458,40460,40463,40465,40467,40469,40471,40473,40475,40478,40480,40482],{"class":94,"line":106},[92,40456,40457],{"class":119},"$url ",[92,40459,126],{"class":98},[92,40461,40462],{"class":102}," Storage",[92,40464,6818],{"class":98},[92,40466,40434],{"class":5161},[92,40468,120],{"class":119},[92,40470,11710],{"class":171},[92,40472,5182],{"class":119},[92,40474,1996],{"class":98},[92,40476,40477],{"class":5161},"url",[92,40479,120],{"class":119},[92,40481,40449],{"class":171},[92,40483,6289],{"class":119},[92,40485,40486,40488,40490,40492,40494,40497],{"class":94,"line":113},[92,40487,40429],{"class":102},[92,40489,6818],{"class":98},[92,40491,26291],{"class":5161},[92,40493,120],{"class":119},[92,40495,40496],{"class":171},"'old-file.txt'",[92,40498,6289],{"class":119},[11,40500,40501,40502,40504,40505,40508],{},"The big benefit is that your code doesn't care ",[1511,40503,34105],{}," the files actually are. You can develop against the local disk and switch to S3 in production just by changing configuration, with no code changes. This abstraction is why file uploads (",[15,40506,40507],{},"$request->file(...)->store(...)",") work the same regardless of backend.",[242,40510,40512],{"id":40511},"_98-how-do-you-send-email-in-laravel","98. How do you send email in Laravel?",[11,40514,40515,40516,40519,40520,40523,40524,81],{},"Laravel provides a clean ",[10490,40517,40518],{},"Mail"," API built around ",[10490,40521,40522],{},"Mailable"," classes, each representing a type of email (a welcome email, an invoice). You generate one with ",[15,40525,40526],{},"php artisan make:mail",[83,40528,40530],{"className":85,"code":40529,"language":87,"meta":88,"style":88},"class WelcomeMail extends Mailable\n{\n    public function build()\n    {\n        return $this->subject('Welcome!')\n            ->markdown('emails.welcome');\n    }\n}\n\n// Send it\nMail::to($user->email)->send(new WelcomeMail());\n",[15,40531,40532,40544,40548,40559,40563,40581,40596,40600,40604,40608,40613],{"__ignoreMap":88},[92,40533,40534,40536,40539,40541],{"class":94,"line":95},[92,40535,6122],{"class":98},[92,40537,40538],{"class":5161}," WelcomeMail",[92,40540,7096],{"class":98},[92,40542,40543],{"class":5161}," Mailable\n",[92,40545,40546],{"class":94,"line":106},[92,40547,11212],{"class":119},[92,40549,40550,40552,40554,40557],{"class":94,"line":113},[92,40551,6132],{"class":98},[92,40553,5659],{"class":98},[92,40555,40556],{"class":5161}," build",[92,40558,27470],{"class":119},[92,40560,40561],{"class":94,"line":138},[92,40562,11267],{"class":119},[92,40564,40565,40567,40569,40571,40574,40576,40579],{"class":94,"line":143},[92,40566,6236],{"class":98},[92,40568,6239],{"class":102},[92,40570,1996],{"class":98},[92,40572,40573],{"class":5161},"subject",[92,40575,120],{"class":119},[92,40577,40578],{"class":171},"'Welcome!'",[92,40580,24307],{"class":119},[92,40582,40583,40586,40589,40591,40594],{"class":94,"line":149},[92,40584,40585],{"class":98},"            ->",[92,40587,40588],{"class":5161},"markdown",[92,40590,120],{"class":119},[92,40592,40593],{"class":171},"'emails.welcome'",[92,40595,6289],{"class":119},[92,40597,40598],{"class":94,"line":155},[92,40599,5104],{"class":119},[92,40601,40602],{"class":94,"line":161},[92,40603,4711],{"class":119},[92,40605,40606],{"class":94,"line":166},[92,40607,110],{"emptyLinePlaceholder":109},[92,40609,40610],{"class":94,"line":187},[92,40611,40612],{"class":134},"// Send it\n",[92,40614,40615,40617,40619,40622,40625,40627,40629,40631,40634,40636,40638,40640],{"class":94,"line":217},[92,40616,40518],{"class":102},[92,40618,6818],{"class":98},[92,40620,40621],{"class":5161},"to",[92,40623,40624],{"class":119},"($user",[92,40626,1996],{"class":98},[92,40628,36897],{"class":119},[92,40630,1996],{"class":98},[92,40632,40633],{"class":5161},"send",[92,40635,120],{"class":119},[92,40637,3334],{"class":98},[92,40639,40538],{"class":102},[92,40641,9268],{"class":119},[11,40643,40644,40645,40648,40649,40652,40653,1517,40655,40658],{},"The email content is typically a Blade or Markdown template, and you configure the mail driver (SMTP, Mailgun, SES, or ",[15,40646,40647],{},"log"," for local testing) in ",[15,40650,40651],{},"config/mail.php",". Because sending email can be slow, you'll often queue it by having the Mailable implement ",[15,40654,38556],{},[15,40656,40657],{},"Mail::to(...)->send(...)"," returns instantly and the email goes out in the background.",[242,40660,40662],{"id":40661},"_99-what-are-notifications-and-how-do-they-support-multiple-channels","99. What are notifications, and how do they support multiple channels?",[11,40664,40665,40668,40669,40671],{},[10490,40666,40667],{},"Notifications"," are a way to inform users about something across different ",[10490,40670,29195],{}," (email, SMS, Slack, database, and more) using a single, unified class. Instead of writing separate code for each medium, one notification defines how it looks on each channel.",[83,40673,40675],{"className":85,"code":40674,"language":87,"meta":88,"style":88},"class InvoicePaid extends Notification\n{\n    public function via($notifiable): array\n    {\n        return ['mail', 'database']; // send via email AND store in DB\n    }\n\n    public function toMail($notifiable) { /* build the email */ }\n    public function toDatabase($notifiable) { /* build the DB record */ }\n}\n\n// Send it\n$user->notify(new InvoicePaid($invoice));\n",[15,40676,40677,40689,40693,40709,40713,40732,40736,40740,40757,40773,40777,40781,40785],{"__ignoreMap":88},[92,40678,40679,40681,40684,40686],{"class":94,"line":95},[92,40680,6122],{"class":98},[92,40682,40683],{"class":5161}," InvoicePaid",[92,40685,7096],{"class":98},[92,40687,40688],{"class":5161}," Notification\n",[92,40690,40691],{"class":94,"line":106},[92,40692,11212],{"class":119},[92,40694,40695,40697,40699,40702,40705,40707],{"class":94,"line":113},[92,40696,6132],{"class":98},[92,40698,5659],{"class":98},[92,40700,40701],{"class":5161}," via",[92,40703,40704],{"class":119},"($notifiable)",[92,40706,5185],{"class":98},[92,40708,33625],{"class":98},[92,40710,40711],{"class":94,"line":138},[92,40712,11267],{"class":119},[92,40714,40715,40717,40719,40722,40724,40727,40729],{"class":94,"line":143},[92,40716,6236],{"class":98},[92,40718,347],{"class":119},[92,40720,40721],{"class":171},"'mail'",[92,40723,195],{"class":119},[92,40725,40726],{"class":171},"'database'",[92,40728,34985],{"class":119},[92,40730,40731],{"class":134},"// send via email AND store in DB\n",[92,40733,40734],{"class":94,"line":149},[92,40735,5104],{"class":119},[92,40737,40738],{"class":94,"line":155},[92,40739,110],{"emptyLinePlaceholder":109},[92,40741,40742,40744,40746,40749,40752,40755],{"class":94,"line":161},[92,40743,6132],{"class":98},[92,40745,5659],{"class":98},[92,40747,40748],{"class":5161}," toMail",[92,40750,40751],{"class":119},"($notifiable) { ",[92,40753,40754],{"class":134},"/* build the email */",[92,40756,4506],{"class":119},[92,40758,40759,40761,40763,40766,40768,40771],{"class":94,"line":166},[92,40760,6132],{"class":98},[92,40762,5659],{"class":98},[92,40764,40765],{"class":5161}," toDatabase",[92,40767,40751],{"class":119},[92,40769,40770],{"class":134},"/* build the DB record */",[92,40772,4506],{"class":119},[92,40774,40775],{"class":94,"line":187},[92,40776,4711],{"class":119},[92,40778,40779],{"class":94,"line":217},[92,40780,110],{"emptyLinePlaceholder":109},[92,40782,40783],{"class":94,"line":712},[92,40784,40612],{"class":134},[92,40786,40787,40789,40791,40794,40796,40798,40800],{"class":94,"line":730},[92,40788,2078],{"class":119},[92,40790,1996],{"class":98},[92,40792,40793],{"class":5161},"notify",[92,40795,120],{"class":119},[92,40797,3334],{"class":98},[92,40799,40683],{"class":102},[92,40801,40802],{"class":119},"($invoice));\n",[11,40804,1792,40805,40808,40809,40811],{},[15,40806,40807],{},"via()"," method decides which channels to use, and a method per channel formats the content. This is powerful for things like \"email the user ",[1511,40810,1505],{}," save an in-app notification\" from one place, and adding a new channel (say, SMS) later is just another method.",[242,40813,40815],{"id":40814},"_100-how-does-localization-work-in-laravel","100. How does localization work in Laravel?",[11,40817,40818,40821,40822,40825],{},[10490,40819,40820],{},"Localization"," lets your app present text in multiple languages. You store translation strings in language files (under ",[15,40823,40824],{},"lang/",") and retrieve them by key, so the same code shows different text depending on the active locale.",[83,40827,40829],{"className":85,"code":40828,"language":87,"meta":88,"style":88},"// lang/en/messages.php  =>  ['welcome' => 'Welcome']\n// lang/es/messages.php  =>  ['welcome' => 'Bienvenido']\n\n__('messages.welcome'); // returns based on current locale\n",[15,40830,40831,40836,40841,40845],{"__ignoreMap":88},[92,40832,40833],{"class":94,"line":95},[92,40834,40835],{"class":134},"// lang/en/messages.php  =>  ['welcome' => 'Welcome']\n",[92,40837,40838],{"class":94,"line":106},[92,40839,40840],{"class":134},"// lang/es/messages.php  =>  ['welcome' => 'Bienvenido']\n",[92,40842,40843],{"class":94,"line":113},[92,40844,110],{"emptyLinePlaceholder":109},[92,40846,40847,40849,40851,40854,40856],{"class":94,"line":138},[92,40848,8191],{"class":5161},[92,40850,120],{"class":119},[92,40852,40853],{"class":171},"'messages.welcome'",[92,40855,653],{"class":119},[92,40857,40858],{"class":134},"// returns based on current locale\n",[11,40860,40861,40862,40865,40866,40869,40870,40873],{},"You set the active locale (for example, from the user's preference) with ",[15,40863,40864],{},"App::setLocale('es')",", and translations can include placeholders (",[15,40867,40868],{},":name",") and handle pluralization. Blade has the ",[15,40871,40872],{},"@lang"," directive too. This keeps user-facing text out of your code and makes supporting new languages a matter of adding translation files, not editing logic.",[242,40875,40877],{"id":40876},"_101-what-is-broadcasting-and-how-does-laravel-do-real-time-events","101. What is broadcasting, and how does Laravel do real-time events?",[11,40879,40880,40883],{},[10490,40881,40882],{},"Broadcasting"," pushes server-side events to the browser in real time over WebSockets, so your UI can update instantly without polling. Think live chat, notifications, or a dashboard that updates as data changes.",[11,40885,40886,40887,40890,40891,40894],{},"It works by taking a Laravel event and \"broadcasting\" it over a WebSocket connection to listening clients. You mark an event with ",[15,40888,40889],{},"ShouldBroadcast",", and on the frontend, ",[10490,40892,40893],{},"Laravel Echo"," subscribes to a channel and reacts when the event arrives.",[83,40896,40898],{"className":85,"code":40897,"language":87,"meta":88,"style":88},"class MessageSent implements ShouldBroadcast\n{\n    public function broadcastOn()\n    {\n        return new PrivateChannel('chat.' . $this->message->room_id);\n    }\n}\n",[15,40899,40900,40912,40916,40927,40931,40959,40963],{"__ignoreMap":88},[92,40901,40902,40904,40907,40909],{"class":94,"line":95},[92,40903,6122],{"class":98},[92,40905,40906],{"class":5161}," MessageSent",[92,40908,7522],{"class":98},[92,40910,40911],{"class":5161}," ShouldBroadcast\n",[92,40913,40914],{"class":94,"line":106},[92,40915,11212],{"class":119},[92,40917,40918,40920,40922,40925],{"class":94,"line":113},[92,40919,6132],{"class":98},[92,40921,5659],{"class":98},[92,40923,40924],{"class":5161}," broadcastOn",[92,40926,27470],{"class":119},[92,40928,40929],{"class":94,"line":138},[92,40930,11267],{"class":119},[92,40932,40933,40935,40937,40940,40942,40945,40947,40949,40951,40954,40956],{"class":94,"line":143},[92,40934,6236],{"class":98},[92,40936,6274],{"class":98},[92,40938,40939],{"class":102}," PrivateChannel",[92,40941,120],{"class":119},[92,40943,40944],{"class":171},"'chat.'",[92,40946,2108],{"class":98},[92,40948,6239],{"class":102},[92,40950,1996],{"class":98},[92,40952,40953],{"class":119},"message",[92,40955,1996],{"class":98},[92,40957,40958],{"class":119},"room_id);\n",[92,40960,40961],{"class":94,"line":149},[92,40962,5104],{"class":119},[92,40964,40965],{"class":94,"line":155},[92,40966,4711],{"class":119},[11,40968,40969,40970,40973],{},"For the WebSocket server itself, Laravel offers ",[10490,40971,40972],{},"Reverb"," (its own first-party server), or you can use Pusher. Channels can be public, private (requiring authorization), or presence (tracking who's online). It's the standard way to add real-time features to a Laravel app.",[242,40975,40977,40978,834,40981,897],{"id":40976},"_102-how-does-pagination-work-and-whats-the-difference-between-paginate-and-simplepaginate","102. How does pagination work, and what's the difference between ",[15,40979,40980],{},"paginate()",[15,40982,40983],{},"simplePaginate()",[11,40985,40986,40989,40990,40993],{},[10490,40987,40988],{},"Pagination"," splits a large result set into pages so you don't load everything at once. Eloquent makes it a one-liner, and it even reads the current page from the URL's ",[15,40991,40992],{},"?page="," query automatically.",[83,40995,40997],{"className":85,"code":40996,"language":87,"meta":88,"style":88},"$posts = Post::paginate(15); // 15 per page\n",[15,40998,40999],{"__ignoreMap":88},[92,41000,41001,41003,41005,41007,41009,41012,41014,41017,41019],{"class":94,"line":95},[92,41002,34405],{"class":119},[92,41004,126],{"class":98},[92,41006,34304],{"class":102},[92,41008,6818],{"class":98},[92,41010,41011],{"class":5161},"paginate",[92,41013,120],{"class":119},[92,41015,41016],{"class":102},"15",[92,41018,653],{"class":119},[92,41020,41021],{"class":134},"// 15 per page\n",[11,41023,41024],{},"The difference between the two methods:",[11016,41026,41027,41036],{},[11019,41028,41029,41031,41032,41035],{},[15,41030,40980],{}," also runs a ",[10490,41033,41034],{},"count query"," to know the total number of records, so it can render numbered page links (1, 2, 3, ... 10) and \"showing X of Y\".",[11019,41037,41038,41040,41041,41044],{},[15,41039,40983],{}," skips the count and only provides ",[10490,41042,41043],{},"\"Previous\" and \"Next\""," links, which is faster on huge tables where counting every row is expensive.",[11,41046,36535,41047,41049,41050,41052,41053,41056],{},[15,41048,40980],{}," when you want full numbered navigation, and ",[15,41051,40983],{}," when you only need next/previous and want to avoid the cost of counting a very large table. In Blade, ",[15,41054,41055],{},"{{ $posts->links() }}"," renders the page links automatically.",[39,41058,41060],{"id":41059},"testing-and-debugging","Testing and Debugging",[242,41062,41064],{"id":41063},"_103-how-does-testing-work-in-laravel-phpunit-and-pest","103. How does testing work in Laravel (PHPUnit and Pest)?",[11,41066,41067,41068,41071,41072,41075,41076,41079,41080,41083],{},"Laravel ships with first-class testing support so you can verify your app behaves correctly. Tests live in the ",[15,41069,41070],{},"tests/"," directory and run with ",[15,41073,41074],{},"php artisan test",". You can write them using ",[10490,41077,41078],{},"PHPUnit"," (the traditional, class-based style) or ",[10490,41081,41082],{},"Pest"," (a newer, cleaner function-based syntax built on top of PHPUnit).",[83,41085,41087],{"className":85,"code":41086,"language":87,"meta":88,"style":88},"// PHPUnit style\npublic function test_homepage_loads()\n{\n    $this->get('/')->assertStatus(200);\n}\n\n// Pest style\nit('loads the homepage', function () {\n    $this->get('/')->assertOk();\n});\n",[15,41088,41089,41094,41105,41109,41137,41141,41145,41150,41166,41187],{"__ignoreMap":88},[92,41090,41091],{"class":94,"line":95},[92,41092,41093],{"class":134},"// PHPUnit style\n",[92,41095,41096,41098,41100,41103],{"class":94,"line":106},[92,41097,6327],{"class":98},[92,41099,5659],{"class":98},[92,41101,41102],{"class":5161}," test_homepage_loads",[92,41104,27470],{"class":119},[92,41106,41107],{"class":94,"line":113},[92,41108,11212],{"class":119},[92,41110,41111,41114,41116,41118,41120,41123,41125,41127,41130,41132,41135],{"class":94,"line":138},[92,41112,41113],{"class":102},"    $this",[92,41115,1996],{"class":98},[92,41117,8985],{"class":5161},[92,41119,120],{"class":119},[92,41121,41122],{"class":171},"'/'",[92,41124,5182],{"class":119},[92,41126,1996],{"class":98},[92,41128,41129],{"class":5161},"assertStatus",[92,41131,120],{"class":119},[92,41133,41134],{"class":102},"200",[92,41136,6289],{"class":119},[92,41138,41139],{"class":94,"line":143},[92,41140,4711],{"class":119},[92,41142,41143],{"class":94,"line":149},[92,41144,110],{"emptyLinePlaceholder":109},[92,41146,41147],{"class":94,"line":155},[92,41148,41149],{"class":134},"// Pest style\n",[92,41151,41152,41155,41157,41160,41162,41164],{"class":94,"line":161},[92,41153,41154],{"class":5161},"it",[92,41156,120],{"class":119},[92,41158,41159],{"class":171},"'loads the homepage'",[92,41161,195],{"class":119},[92,41163,3556],{"class":98},[92,41165,32636],{"class":119},[92,41167,41168,41170,41172,41174,41176,41178,41180,41182,41185],{"class":94,"line":166},[92,41169,41113],{"class":102},[92,41171,1996],{"class":98},[92,41173,8985],{"class":5161},[92,41175,120],{"class":119},[92,41177,41122],{"class":171},[92,41179,5182],{"class":119},[92,41181,1996],{"class":98},[92,41183,41184],{"class":5161},"assertOk",[92,41186,7730],{"class":119},[92,41188,41189],{"class":94,"line":187},[92,41190,11624],{"class":119},[11,41192,41193],{},"Laravel provides expressive testing helpers: you can make fake HTTP requests, assert on responses, interact with the database, fake queues and mail, and act as a logged-in user. This makes it easy to write tests that exercise real application behavior, and interviewers like to see that you actually write them.",[242,41195,41197],{"id":41196},"_104-what-is-the-difference-between-feature-tests-and-unit-tests","104. What is the difference between feature tests and unit tests?",[11,41199,41200,41201,834,41204,41207],{},"The two live in different folders (",[15,41202,41203],{},"tests/Feature",[15,41205,41206],{},"tests/Unit",") and test at different levels.",[11,41209,6686,41210,41213],{},[10490,41211,41212],{},"unit test"," checks a small, isolated piece of code, like a single method or class, without booting the whole framework or touching the database. It's fast and focused: given this input, does this function return the right output?",[11,41215,6686,41216,41219,41220,41223],{},[10490,41217,41218],{},"feature test"," checks a larger slice of behavior, often a full request-to-response cycle, with the framework booted and the database available. For example, \"posting to ",[15,41221,41222],{},"/register"," creates a user and redirects to the dashboard.\"",[83,41225,41227],{"className":85,"code":41226,"language":87,"meta":88,"style":88},"// Feature test\n$this->post('/register', [...])->assertRedirect('/dashboard');\n$this->assertDatabaseHas('users', ['email' => 'a@b.com']);\n",[15,41228,41229,41234,41264],{"__ignoreMap":88},[92,41230,41231],{"class":94,"line":95},[92,41232,41233],{"class":134},"// Feature test\n",[92,41235,41236,41238,41240,41242,41244,41247,41249,41251,41253,41255,41258,41260,41262],{"class":94,"line":106},[92,41237,6100],{"class":102},[92,41239,1996],{"class":98},[92,41241,11637],{"class":5161},[92,41243,120],{"class":119},[92,41245,41246],{"class":171},"'/register'",[92,41248,2708],{"class":119},[92,41250,5335],{"class":98},[92,41252,32402],{"class":119},[92,41254,1996],{"class":98},[92,41256,41257],{"class":5161},"assertRedirect",[92,41259,120],{"class":119},[92,41261,32650],{"class":171},[92,41263,6289],{"class":119},[92,41265,41266,41268,41270,41273,41275,41277,41279,41281,41283,41286],{"class":94,"line":113},[92,41267,6100],{"class":102},[92,41269,1996],{"class":98},[92,41271,41272],{"class":5161},"assertDatabaseHas",[92,41274,120],{"class":119},[92,41276,32708],{"class":171},[92,41278,2708],{"class":119},[92,41280,34977],{"class":171},[92,41282,1019],{"class":98},[92,41284,41285],{"class":171}," 'a@b.com'",[92,41287,11674],{"class":119},[11,41289,41290,41291,41294],{},"In Laravel apps you'll usually write more ",[10490,41292,41293],{},"feature tests",", because they verify that the pieces actually work together, which is closer to what users experience.",[242,41296,41298,41299,834,41302,41305],{"id":41297},"_105-what-do-the-refreshdatabase-and-databasetransactions-traits-do","105. What do the ",[15,41300,41301],{},"RefreshDatabase",[15,41303,41304],{},"DatabaseTransactions"," traits do?",[11,41307,41308],{},"Both keep your database clean between tests so one test doesn't leave data behind that affects another, but they work differently.",[11,41310,41311,41313,41314,41317],{},[15,41312,41301],{}," runs your ",[10490,41315,41316],{},"migrations"," for the test database and resets it between tests (using transactions where possible) so every test starts from a known, empty schema.",[11,41319,41320,41322,41323,41326],{},[15,41321,41304],{}," wraps ",[10490,41324,41325],{},"each test in a transaction"," and rolls it back at the end, undoing any changes without re-migrating. It's faster but assumes the schema is already in place.",[83,41328,41330],{"className":85,"code":41329,"language":87,"meta":88,"style":88},"class PostTest extends TestCase\n{\n    use RefreshDatabase; // fresh, migrated DB for each test\n}\n",[15,41331,41332,41344,41348,41360],{"__ignoreMap":88},[92,41333,41334,41336,41339,41341],{"class":94,"line":95},[92,41335,6122],{"class":98},[92,41337,41338],{"class":5161}," PostTest",[92,41340,7096],{"class":98},[92,41342,41343],{"class":5161}," TestCase\n",[92,41345,41346],{"class":94,"line":106},[92,41347,11212],{"class":119},[92,41349,41350,41352,41355,41357],{"class":94,"line":113},[92,41351,7819],{"class":98},[92,41353,41354],{"class":102}," RefreshDatabase",[92,41356,975],{"class":119},[92,41358,41359],{"class":134},"// fresh, migrated DB for each test\n",[92,41361,41362],{"class":94,"line":138},[92,41363,4711],{"class":119},[11,41365,41366,41367,41369],{},"The practical takeaway is that these traits give each test an isolated, predictable database state, which is essential for reliable tests. ",[15,41368,41301],{}," is the most commonly used because it's the safest default.",[242,41371,41373,41374,195,41377,394,41380,897],{"id":41372},"_106-what-is-the-difference-between-dd-dump-and-ddd","106. What is the difference between ",[15,41375,41376],{},"dd()",[15,41378,41379],{},"dump()",[15,41381,41382],{},"ddd()",[11,41384,41385],{},"All three are debugging helpers for inspecting values, differing in whether they stop execution and how much detail they show.",[11016,41387,41388,41398,41407],{},[11019,41389,41390,41393,41394,41397],{},[15,41391,41392],{},"dump($var)"," prints the value in a readable format and ",[10490,41395,41396],{},"keeps going",", so you can dump several things in one run.",[11019,41399,41400,41402,41403,41406],{},[15,41401,39814],{}," means \"dump and die\": it prints the value and ",[10490,41404,41405],{},"halts execution"," immediately, so nothing after it runs.",[11019,41408,41409,41412,41413,41415],{},[15,41410,41411],{},"ddd($var)"," is \"dump, die, and debug\": like ",[15,41414,41376],{},", but also shows extra debugging context (a stack trace and more), when Laravel Ignition is available.",[83,41417,41419],{"className":85,"code":41418,"language":87,"meta":88,"style":88},"dump($user);   // shows it, continues\ndd($user);     // shows it, stops here\n",[15,41420,41421,41432],{"__ignoreMap":88},[92,41422,41423,41426,41429],{"class":94,"line":95},[92,41424,41425],{"class":5161},"dump",[92,41427,41428],{"class":119},"($user);   ",[92,41430,41431],{"class":134},"// shows it, continues\n",[92,41433,41434,41437,41440],{"class":94,"line":106},[92,41435,41436],{"class":5161},"dd",[92,41438,41439],{"class":119},"($user);     ",[92,41441,41442],{"class":134},"// shows it, stops here\n",[11,41444,41445,41446,41448,41449,41451],{},"You reach for ",[15,41447,41379],{}," when you want to peek without interrupting the flow, and ",[15,41450,41376],{}," when you want to stop and examine a value at a specific point. They're the quickest way to see what your code is actually doing.",[39,41453,41455],{"id":41454},"advanced-and-best-practices","Advanced and Best Practices",[242,41457,41459],{"id":41458},"_107-what-is-the-difference-between-using-a-facade-and-dependency-injection-and-when-should-you-prefer-each","107. What is the difference between using a facade and dependency injection, and when should you prefer each?",[11,41461,41462],{},"Both give you access to a service, but they express the dependency differently.",[11,41464,6686,41465,3559,41467,41469,41470,41472],{},[10490,41466,31724],{},[15,41468,31846],{},") is a convenient static-looking call you can use anywhere without declaring anything. ",[10490,41471,31524],{}," asks for the service in the constructor, so the class's dependencies are explicit and visible.",[83,41474,41476],{"className":85,"code":41475,"language":87,"meta":88,"style":88},"// Facade: convenient, but the dependency is hidden\nCache::get('key');\n\n// Injection: explicit and easy to mock in tests\npublic function __construct(private Repository $cache) {}\n",[15,41477,41478,41483,41497,41501,41506],{"__ignoreMap":88},[92,41479,41480],{"class":94,"line":95},[92,41481,41482],{"class":134},"// Facade: convenient, but the dependency is hidden\n",[92,41484,41485,41487,41489,41491,41493,41495],{"class":94,"line":106},[92,41486,31754],{"class":102},[92,41488,6818],{"class":98},[92,41490,8985],{"class":5161},[92,41492,120],{"class":119},[92,41494,12952],{"class":171},[92,41496,6289],{"class":119},[92,41498,41499],{"class":94,"line":113},[92,41500,110],{"emptyLinePlaceholder":109},[92,41502,41503],{"class":94,"line":138},[92,41504,41505],{"class":134},"// Injection: explicit and easy to mock in tests\n",[92,41507,41508,41510,41512,41514,41516,41518,41521],{"class":94,"line":143},[92,41509,6327],{"class":98},[92,41511,5659],{"class":98},[92,41513,6163],{"class":102},[92,41515,120],{"class":119},[92,41517,6335],{"class":98},[92,41519,41520],{"class":102}," Repository",[92,41522,31870],{"class":119},[11,41524,41525,41526,41529],{},"Facades are great for quick, readable code and are perfectly testable (they can be faked). Dependency injection is often preferred in larger classes or packages because it makes dependencies obvious and swappable, which many teams consider cleaner architecture. In practice, plenty of Laravel code mixes both; the important thing is understanding they resolve to the ",[1511,41527,41528],{},"same"," underlying service.",[242,41531,41533],{"id":41532},"_108-what-are-macros-in-laravel","108. What are macros in Laravel?",[11,41535,41536,41539,41540,195,41542,195,41545,41547,41548,41551],{},[10490,41537,41538],{},"Macros"," let you add your own custom methods to Laravel's built-in classes (like ",[15,41541,39325],{},[15,41543,41544],{},"Str",[15,41546,11537],{},", or the query builder) at runtime, without editing the framework's source. Any class using the ",[15,41549,41550],{},"Macroable"," trait can be extended this way.",[83,41553,41555],{"className":85,"code":41554,"language":87,"meta":88,"style":88},"// Add a custom method to Collection (e.g. in a service provider's boot())\nCollection::macro('toUpper', function () {\n    return $this->map(fn ($value) => strtoupper($value));\n});\n\n// Now available everywhere\ncollect(['a', 'b'])->toUpper(); // ['A', 'B']\n",[15,41556,41557,41562,41582,41603,41607,41611,41616],{"__ignoreMap":88},[92,41558,41559],{"class":94,"line":95},[92,41560,41561],{"class":134},"// Add a custom method to Collection (e.g. in a service provider's boot())\n",[92,41563,41564,41566,41568,41571,41573,41576,41578,41580],{"class":94,"line":106},[92,41565,39325],{"class":102},[92,41567,6818],{"class":98},[92,41569,41570],{"class":5161},"macro",[92,41572,120],{"class":119},[92,41574,41575],{"class":171},"'toUpper'",[92,41577,195],{"class":119},[92,41579,3556],{"class":98},[92,41581,32636],{"class":119},[92,41583,41584,41586,41588,41590,41592,41594,41596,41598,41600],{"class":94,"line":113},[92,41585,5195],{"class":98},[92,41587,6239],{"class":102},[92,41589,1996],{"class":98},[92,41591,26597],{"class":5161},[92,41593,120],{"class":119},[92,41595,3466],{"class":98},[92,41597,34739],{"class":119},[92,41599,2326],{"class":102},[92,41601,41602],{"class":119},"($value));\n",[92,41604,41605],{"class":94,"line":138},[92,41606,11624],{"class":119},[92,41608,41609],{"class":94,"line":143},[92,41610,110],{"emptyLinePlaceholder":109},[92,41612,41613],{"class":94,"line":149},[92,41614,41615],{"class":134},"// Now available everywhere\n",[92,41617,41618,41621,41623,41625,41627,41629,41631,41633,41636,41638],{"class":94,"line":155},[92,41619,41620],{"class":5161},"collect",[92,41622,486],{"class":119},[92,41624,1844],{"class":171},[92,41626,195],{"class":119},[92,41628,198],{"class":171},[92,41630,32402],{"class":119},[92,41632,1996],{"class":98},[92,41634,41635],{"class":5161},"toUpper",[92,41637,27477],{"class":119},[92,41639,41640],{"class":134},"// ['A', 'B']\n",[11,41642,41643,41644,41646],{},"Macros are handy for adding a reusable helper you wish the framework had, in a clean way. You typically register them in a service provider's ",[15,41645,31659],{}," method so they're available throughout the app. They're a good example of how extensible Laravel is.",[242,41648,41650],{"id":41649},"_109-what-is-the-repository-pattern-and-is-it-necessary-in-laravel","109. What is the Repository pattern, and is it necessary in Laravel?",[11,41652,1792,41653,41656],{},[10490,41654,41655],{},"Repository pattern"," puts a layer of abstraction between your business logic and your data access, so the rest of the app talks to a repository interface instead of Eloquent directly. The idea is that you could swap the data source without touching the code that uses it.",[83,41658,41660],{"className":85,"code":41659,"language":87,"meta":88,"style":88},"interface UserRepository\n{\n    public function findActive(): Collection;\n}\n",[15,41661,41662,41669,41673,41691],{"__ignoreMap":88},[92,41663,41664,41666],{"class":94,"line":95},[92,41665,7434],{"class":98},[92,41667,41668],{"class":5161}," UserRepository\n",[92,41670,41671],{"class":94,"line":106},[92,41672,11212],{"class":119},[92,41674,41675,41677,41679,41682,41684,41686,41689],{"class":94,"line":113},[92,41676,6132],{"class":98},[92,41678,5659],{"class":98},[92,41680,41681],{"class":5161}," findActive",[92,41683,6042],{"class":119},[92,41685,5185],{"class":98},[92,41687,41688],{"class":102}," Collection",[92,41690,229],{"class":119},[92,41692,41693],{"class":94,"line":138},[92,41694,4711],{"class":119},[11,41696,41697,41698,41701],{},"Whether it's ",[1511,41699,41700],{},"necessary"," is a genuine debate, and a good answer shows you understand the trade-off. Because Eloquent already acts as an abstraction over the database, many Laravel developers consider a repository layer redundant boilerplate for typical apps. It can add value in very large codebases where you want to isolate business logic from the ORM or make swapping implementations easier, but for most projects it adds complexity without much benefit. The honest answer is \"it depends on the project,\" not \"always use it.\"",[242,41703,41705,41706,834,41709,41712],{"id":41704},"_110-what-is-the-difference-between-hash-and-encrypt-in-laravel","110. What is the difference between ",[15,41707,41708],{},"hash",[15,41710,41711],{},"encrypt"," in Laravel?",[11,41714,41715,41716,394,41719,81],{},"They both protect data, but with a crucial difference: ",[10490,41717,41718],{},"hashing is one-way",[10490,41720,41721],{},"encryption is two-way",[11,41723,41724,3559,41727,41730,41731,41734],{},[10490,41725,41726],{},"Hashing",[15,41728,41729],{},"Hash::make()",") transforms data into a fixed fingerprint that ",[10490,41732,41733],{},"cannot be reversed",". You use it for passwords, where you never need the original back; you only compare a fresh hash against the stored one at login.",[11,41736,41737,3559,41740,41743,41744,41747],{},[10490,41738,41739],{},"Encryption",[15,41741,41742],{},"Crypt::encryptString()",") transforms data so it ",[10490,41745,41746],{},"can be decrypted"," back to the original with the app key. You use it for sensitive data you need to read again later, like storing an API token or a user's private note.",[83,41749,41751],{"className":85,"code":41750,"language":87,"meta":88,"style":88},"Hash::make($password);          // one-way, for passwords\nCrypt::encryptString($secret);  // reversible, decrypt later\n",[15,41752,41753,41767],{"__ignoreMap":88},[92,41754,41755,41757,41759,41761,41764],{"class":94,"line":95},[92,41756,38240],{"class":102},[92,41758,6818],{"class":98},[92,41760,26148],{"class":5161},[92,41762,41763],{"class":119},"($password);          ",[92,41765,41766],{"class":134},"// one-way, for passwords\n",[92,41768,41769,41772,41774,41777,41780],{"class":94,"line":106},[92,41770,41771],{"class":102},"Crypt",[92,41773,6818],{"class":98},[92,41775,41776],{"class":5161},"encryptString",[92,41778,41779],{"class":119},"($secret);  ",[92,41781,41782],{"class":134},"// reversible, decrypt later\n",[11,41784,41785],{},"The key insight interviewers look for: never \"encrypt\" a password (you should never be able to recover it), and never \"hash\" data you'll need to read back. Choosing the wrong one is a real security mistake.",[242,41787,41789],{"id":41788},"_111-what-are-some-common-ways-to-optimize-a-laravel-application-for-production","111. What are some common ways to optimize a Laravel application for production?",[11,41791,41792],{},"Optimizing a Laravel app is a mix of framework-level caching and good coding practices. The most common steps:",[11016,41794,41795,41812,41821,41827,41836,41845],{},[11019,41796,41797,41800,41801,41804,41805,195,41807,394,41809,41811],{},[10490,41798,41799],{},"Cache config, routes, and views"," on deploy with ",[15,41802,41803],{},"php artisan optimize"," (which runs ",[15,41806,32199],{},[15,41808,32202],{},[15,41810,32205],{},"), so Laravel does less work per request.",[11019,41813,41814,41817,41818,41820],{},[10490,41815,41816],{},"Fix N+1 queries"," with eager loading (",[15,41819,34462],{},"), and add database indexes for columns you filter and sort on.",[11019,41822,41823,41826],{},[10490,41824,41825],{},"Use queues"," for slow tasks (email, image processing) so requests return fast.",[11019,41828,41829,41832,41833,41835],{},[10490,41830,41831],{},"Cache expensive data"," (queries, computed values) with ",[15,41834,39081],{}," using Redis.",[11019,41837,41838,41841,41842,81],{},[10490,41839,41840],{},"Enable OPcache"," on the server so PHP doesn't recompile your code on every request, and use ",[15,41843,41844],{},"composer install --optimize-autoloader --no-dev",[11019,41846,41847,3559,41850,41852,41853,41856],{},[10490,41848,41849],{},"Use a long-running worker",[15,41851,38568],{},") managed by a supervisor, and consider ",[10490,41854,41855],{},"Laravel Octane"," for high-traffic apps.",[11,41858,41859],{},"The theme is: do work ahead of time (caching), avoid unnecessary database round-trips, and push slow work into the background. These few habits handle the vast majority of real-world performance problems.",[39,41861,41863],{"id":41862},"final-thoughts","Final Thoughts",[11,41865,41866,41867,41870,41871,41873,41874,41876,41877,41879],{},"These 111 questions cover the ground that comes up again and again in Laravel interviews, from the request lifecycle and the service container to Eloquent relationships, queues, and authentication. Don't try to memorize every answer word for word. Build the underlying mental model instead: understand ",[1511,41868,41869],{},"why"," eager loading fixes N+1, ",[1511,41872,41869],{}," config caching breaks stray ",[15,41875,13914],{}," calls, ",[1511,41878,41869],{}," a facade and an injected contract reach the same service. Once that understanding is solid, you'll be able to reason through questions phrased in ways you've never seen before, which is really what interviewers are testing for.",[11,41881,41882],{},"Good luck with your interviews.",[10887,41884,41885],{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .s4JwU, html code.shiki .s4JwU{--shiki-default:#85E89D}",{"title":88,"searchDepth":106,"depth":106,"links":41887},[41888,41904,41912,41922,41929,41940,41969,41977,41989,42000,42013,42021,42028,42035,42044,42052,42060],{"id":31365,"depth":106,"text":31366,"children":41889},[41890,41891,41892,41893,41894,41895,41896,41898,41899,41900,41902],{"id":31369,"depth":113,"text":31370},{"id":31381,"depth":113,"text":31382},{"id":31426,"depth":113,"text":31427},{"id":31492,"depth":113,"text":31493},{"id":31518,"depth":113,"text":31519},{"id":31643,"depth":113,"text":31644},{"id":31676,"depth":113,"text":41897},"7. What is the difference between the register() and boot() methods of a service provider?",{"id":31718,"depth":113,"text":31719},{"id":31822,"depth":113,"text":31823},{"id":31876,"depth":113,"text":41901},"10. How does Laravel handle environment configuration with the .env file?",{"id":31905,"depth":113,"text":41903},"11. What is the difference between env() and config(), and why should you not call env() outside config files?",{"id":31968,"depth":106,"text":31969,"children":41905},[41906,41907,41908,41910],{"id":31972,"depth":113,"text":31973},{"id":32003,"depth":113,"text":32004},{"id":32121,"depth":113,"text":41909},"14. What does php artisan tinker do?",{"id":32195,"depth":113,"text":41911},"15. What do the optimization commands like config:cache, route:cache, and view:cache do, and when should you run them?",{"id":32243,"depth":106,"text":32244,"children":41913},[41914,41915,41916,41917,41918,41920,41921],{"id":32247,"depth":113,"text":32248},{"id":32363,"depth":113,"text":32364},{"id":32489,"depth":113,"text":32490},{"id":32568,"depth":113,"text":32569},{"id":32733,"depth":113,"text":41919},"20. What is the difference between the web and api middleware groups?",{"id":32763,"depth":113,"text":32764},{"id":32836,"depth":113,"text":32837},{"id":31476,"depth":106,"text":32902,"children":41923},[41924,41925,41926,41927,41928],{"id":32905,"depth":113,"text":32906},{"id":32921,"depth":113,"text":32922},{"id":32966,"depth":113,"text":32967},{"id":33083,"depth":113,"text":33084},{"id":33227,"depth":113,"text":33228},{"id":33247,"depth":106,"text":33248,"children":41930},[41931,41932,41933,41934,41935,41937,41938],{"id":33251,"depth":113,"text":33252},{"id":33335,"depth":113,"text":33336},{"id":33437,"depth":113,"text":33438},{"id":33521,"depth":113,"text":33522},{"id":33718,"depth":113,"text":41936},"32. What is the difference between $request->input(), $request->query(), and $request->all()?",{"id":33791,"depth":113,"text":33792},{"id":33885,"depth":113,"text":41939},"34. What is old input flashing, and how does ->withInput() help?",{"id":33992,"depth":106,"text":33993,"children":41941},[41942,41943,41944,41945,41946,41948,41949,41950,41952,41953,41954,41955,41957,41959,41961,41963,41964,41965,41966,41967],{"id":33996,"depth":113,"text":33997},{"id":34077,"depth":113,"text":34078},{"id":34196,"depth":113,"text":34197},{"id":34388,"depth":113,"text":34389},{"id":34533,"depth":113,"text":41947},"39. What is the difference between with(), load(), and withCount()?",{"id":34663,"depth":113,"text":34664},{"id":34789,"depth":113,"text":34790},{"id":34904,"depth":113,"text":41951},"42. What is mass assignment, and what's the difference between $fillable and $guarded?",{"id":35025,"depth":113,"text":35026},{"id":35138,"depth":113,"text":35139},{"id":35228,"depth":113,"text":35229},{"id":35312,"depth":113,"text":41956},"46. What is the difference between find(), first(), firstOrFail(), and findOrFail()?",{"id":35462,"depth":113,"text":41958},"47. What is the difference between get() and all()?",{"id":35571,"depth":113,"text":41960},"48. What is the difference between save(), create(), and update()?",{"id":35724,"depth":113,"text":41962},"49. What do firstOrCreate(), firstOrNew(), and updateOrCreate() do?",{"id":35857,"depth":113,"text":35858},{"id":36009,"depth":113,"text":36010},{"id":36173,"depth":113,"text":36174},{"id":36266,"depth":113,"text":36267},{"id":36429,"depth":113,"text":41968},"54. What is the difference between pluck() and select()?",{"id":36544,"depth":106,"text":36545,"children":41970},[41971,41972,41974,41975,41976],{"id":36548,"depth":113,"text":36549},{"id":36650,"depth":113,"text":41973},"56. What is the difference between migrate, migrate:rollback, migrate:refresh, and migrate:fresh?",{"id":36727,"depth":113,"text":36728},{"id":36853,"depth":113,"text":36854},{"id":36921,"depth":113,"text":36922},{"id":37026,"depth":106,"text":37027,"children":41978},[41979,41980,41982,41984,41985,41987],{"id":37030,"depth":113,"text":37031},{"id":37056,"depth":113,"text":41981},"61. What is the difference between {{ }} and {!! !!}?",{"id":37132,"depth":113,"text":41983},"62. What are Blade layouts using @extends, @section, and @yield?",{"id":37283,"depth":113,"text":37284},{"id":37398,"depth":113,"text":41986},"64. What is the difference between @include and a Blade component?",{"id":37428,"depth":113,"text":41988},"65. What do directives like @forelse, @isset, and @auth do?",{"id":37547,"depth":106,"text":37548,"children":41990},[41991,41992,41993,41994,41995,41996,41997,41998,41999],{"id":37551,"depth":113,"text":37552},{"id":37578,"depth":113,"text":37579},{"id":37611,"depth":113,"text":37612},{"id":37718,"depth":113,"text":37719},{"id":37745,"depth":113,"text":37746},{"id":37880,"depth":113,"text":37881},{"id":37924,"depth":113,"text":37925},{"id":38029,"depth":113,"text":38030},{"id":38168,"depth":113,"text":38169},{"id":38268,"depth":106,"text":38269,"children":42001},[42002,42003,42004,42005,42006,42008,42009,42011,42012],{"id":38272,"depth":113,"text":38273},{"id":38372,"depth":113,"text":38373},{"id":38420,"depth":113,"text":38421},{"id":38442,"depth":113,"text":38443},{"id":38564,"depth":113,"text":42007},"79. What is the difference between queue:work and queue:listen?",{"id":38610,"depth":113,"text":38611},{"id":38668,"depth":113,"text":42010},"81. What is the sync queue driver, and when is it used?",{"id":38712,"depth":113,"text":38713},{"id":38877,"depth":113,"text":38878},{"id":38957,"depth":106,"text":38958,"children":42014},[42015,42016,42018,42019],{"id":38961,"depth":113,"text":38962},{"id":39077,"depth":113,"text":42017},"85. What does Cache::remember() do?",{"id":39164,"depth":113,"text":39165},{"id":39271,"depth":113,"text":42020},"87. How does config caching affect the use of env()?",{"id":39315,"depth":106,"text":39316,"children":42022},[42023,42024,42026,42027],{"id":39319,"depth":113,"text":39320},{"id":39428,"depth":113,"text":42025},"89. What is the difference between map(), filter(), reduce(), and each() on a collection?",{"id":39637,"depth":113,"text":39638},{"id":39758,"depth":113,"text":39759},{"id":39828,"depth":106,"text":39829,"children":42029},[42030,42031,42032,42033,42034],{"id":39832,"depth":113,"text":39833},{"id":39933,"depth":113,"text":39934},{"id":40079,"depth":113,"text":40080},{"id":40222,"depth":113,"text":40223},{"id":40292,"depth":113,"text":40293},{"id":40405,"depth":106,"text":40406,"children":42036},[42037,42038,42039,42040,42041,42042],{"id":40409,"depth":113,"text":40410},{"id":40511,"depth":113,"text":40512},{"id":40661,"depth":113,"text":40662},{"id":40814,"depth":113,"text":40815},{"id":40876,"depth":113,"text":40877},{"id":40976,"depth":113,"text":42043},"102. How does pagination work, and what's the difference between paginate() and simplePaginate()?",{"id":41059,"depth":106,"text":41060,"children":42045},[42046,42047,42048,42050],{"id":41063,"depth":113,"text":41064},{"id":41196,"depth":113,"text":41197},{"id":41297,"depth":113,"text":42049},"105. What do the RefreshDatabase and DatabaseTransactions traits do?",{"id":41372,"depth":113,"text":42051},"106. What is the difference between dd(), dump(), and ddd()?",{"id":41454,"depth":106,"text":41455,"children":42053},[42054,42055,42056,42057,42059],{"id":41458,"depth":113,"text":41459},{"id":41532,"depth":113,"text":41533},{"id":41649,"depth":113,"text":41650},{"id":41704,"depth":113,"text":42058},"110. What is the difference between hash and encrypt in Laravel?",{"id":41788,"depth":113,"text":41789},{"id":41862,"depth":106,"text":41863},"2026-08-13","111 real, commonly-asked Laravel interview questions and answers for developers with 0-3 years of experience, covering the request lifecycle, Eloquent, routing, middleware, queues, authentication, Blade, and testing, explained in the simplest terms.","top-111-laravel-interview-questions.png",{},"/backend/top-111-laravel-interview-questions",{"title":31344,"description":42062},"Backend/7.top-111-laravel-interview-questions",[15398,10975,42069,10977,34002,10979],"Interview Questions","r9RbbxjY1ozOeQWEg6usXX_qfnj4w6hPmJYcWvbw_VU",{"id":42072,"title":42073,"author":6,"body":42074,"date":46940,"description":46941,"draft":10966,"extension":10967,"guide":10968,"image":46942,"meta":46943,"navigation":109,"path":46944,"seo":46945,"stem":46946,"tags":46947,"__hash__":46951},"blog/Backend/6.top-111-backend-interview-questions.md","Top 111 Backend Interview Questions and Answers",{"type":8,"value":42075,"toc":46803},[42076,42079,42085,42089,42093,42100,42198,42222,42226,42238,42276,42280,42286,42326,42330,42347,42410,42419,42423,42436,42450,42454,42468,42479,42483,42489,42524,42528,42542,42549,42571,42581,42585,42591,42594,42598,42601,42611,42621,42634,42680,42687,42693,42707,42727,42740,42746,42749,42775,42790,42794,42799,42802,42806,42812,42818,42822,42826,42832,42835,42878,42884,42888,42898,42960,42963,42967,42973,43045,43052,43056,43061,43071,43084,43088,43095,43105,43109,43115,43121,43150,43154,43167,43178,43184,43196,43200,43206,43216,43220,43223,43226,43310,43313,43317,43327,43330,43334,43348,43351,43355,43365,43368,43371,43374,43378,43384,43388,43394,43409,43413,43416,43430,43459,43498,43501,43505,43511,43521,43525,43534,43551,43566,43570,43579,43605,43609,43621,43631,43635,43645,43651,43655,43661,43722,43785,43806,43810,43815,43821,43847,43927,43933,43937,43943,44004,44007,44031,44039,44043,44049,44052,44056,44070,44076,44088,44092,44099,44102,44106,44120,44126,44132,44138,44142,44159,44166,44173,44177,44181,44191,44248,44251,44255,44258,44333,44336,44340,44347,44353,44437,44440,44444,44454,44457,44461,44467,44486,44493,44500,44504,44517,44520,44524,44535,44542,44546,44552,44558,44562,44566,44574,44581,44585,44599,44661,44664,44668,44676,44682,44709,44714,44725,44741,44757,44798,44810,44814,44820,44827,44850,44856,44859,44863,44874,44884,44888,44911,44927,44933,44936,44940,44945,44951,44955,44960,44985,44989,44994,45011,45015,45020,45104,45110,45154,45157,45161,45166,45169,45173,45179,45182,45186,45196,45202,45206,45215,45221,45224,45228,45233,45240,45244,45247,45310,45316,45320,45334,45340,45346,45349,45353,45359,45418,45429,45433,45449,45452,45456,45462,45465,45469,45475,45478,45482,45492,45554,45560,45564,45568,45578,45581,45585,45594,45600,45604,45610,45616,45622,45626,45631,45634,45660,45663,45667,45677,45680,45684,45690,45693,45699,45702,45706,45716,45719,45723,45733,45736,45740,45746,45749,45753,45759,45762,45766,45770,45780,45838,45841,45845,45851,45854,45900,45903,45909,45913,45922,45925,45929,45935,45938,45942,45952,46021,46024,46028,46034,46049,46053,46059,46062,46066,46080,46086,46090,46100,46103,46106,46110,46116,46131,46134,46138,46145,46148,46154,46201,46204,46208,46218,46221,46225,46229,46235,46242,46248,46252,46266,46269,46273,46283,46286,46290,46293,46342,46345,46349,46355,46358,46362,46368,46375,46379,46385,46388,46392,46396,46402,46467,46470,46474,46480,46483,46487,46500,46503,46507,46517,46587,46590,46594,46604,46607,46611,46618,46632,46645,46649,46662,46681,46684,46688,46698,46758,46761,46765,46771,46777,46780,46784,46787,46793,46795,46798,46800],[11,42077,42078],{},"Backend interviews rarely hinge on trivia. They test whether you understand how a request actually flows through a system: what happens between a client sending an HTTP request and a server writing to a database, why a cache can go stale, what happens when two transactions touch the same row at the same time. Get those mental models right, and you can reason through a question you have never seen phrased quite that way before, even under interview pressure.",[11,42080,42081,42082,42084],{},"This article collects 111 of the most commonly asked backend interview questions, aimed at developers with zero to three years of experience. It deliberately stays framework-agnostic: you will not find a single question about a specific web framework here, those get their own dedicated articles, like the ",[23,42083,26],{"href":25},". What you will find is the stuff that shows up in almost every backend interview regardless of which language or framework the job actually uses: HTTP fundamentals, API design, relational and NoSQL databases, authentication and security, caching, concurrency, distributed systems, messaging, and testing and deployment. Each answer starts with a clear, simple definition, explains the reasoning behind it, and includes a short example, code snippet, or diagram only where it genuinely helps the idea stick.",[39,42086,42088],{"id":42087},"http-and-web-fundamentals","HTTP and Web Fundamentals",[242,42090,42092],{"id":42091},"_1-what-are-the-main-http-methods-and-when-do-you-use-each-get-post-put-patch-delete","1. What are the main HTTP methods and when do you use each (GET, POST, PUT, PATCH, DELETE)?",[11,42094,42095,42096,42099],{},"HTTP methods (also called ",[10490,42097,42098],{},"verbs",") tell the server what kind of action the client wants to perform on a resource. Picking the right one is part of what makes an API predictable to use.",[4068,42101,42102,42118],{},[4071,42103,42104],{},[4074,42105,42106,42109,42112,42115],{},[4077,42107,42108],{},"Method",[4077,42110,42111],{},"Purpose",[4077,42113,42114],{},"Has body?",[4077,42116,42117],{},"Typical use",[4090,42119,42120,42136,42152,42167,42182],{},[4074,42121,42122,42127,42130,42133],{},[4095,42123,42124],{},[15,42125,42126],{},"GET",[4095,42128,42129],{},"Retrieve a resource",[4095,42131,42132],{},"No",[4095,42134,42135],{},"Fetch a user, list products",[4074,42137,42138,42143,42146,42149],{},[4095,42139,42140],{},[15,42141,42142],{},"POST",[4095,42144,42145],{},"Create a new resource",[4095,42147,42148],{},"Yes",[4095,42150,42151],{},"Create an order, submit a form",[4074,42153,42154,42159,42162,42164],{},[4095,42155,42156],{},[15,42157,42158],{},"PUT",[4095,42160,42161],{},"Replace a resource entirely",[4095,42163,42148],{},[4095,42165,42166],{},"Overwrite a user's full profile",[4074,42168,42169,42174,42177,42179],{},[4095,42170,42171],{},[15,42172,42173],{},"PATCH",[4095,42175,42176],{},"Partially update a resource",[4095,42178,42148],{},[4095,42180,42181],{},"Update just a user's email",[4074,42183,42184,42189,42192,42195],{},[4095,42185,42186],{},[15,42187,42188],{},"DELETE",[4095,42190,42191],{},"Remove a resource",[4095,42193,42194],{},"Usually no",[4095,42196,42197],{},"Delete a comment",[11,42199,42200,42202,42203,14005,42206,42208,42209,195,42211,394,42213,42215,42216,42218,42219,42221],{},[15,42201,42126],{}," requests should never change data on the server; that's what makes them ",[10490,42204,42205],{},"safe",[15,42207,42142],{}," is the odd one out because calling it twice usually creates two resources, while ",[15,42210,42158],{},[15,42212,42173],{},[15,42214,42188],{}," are generally designed so that repeating the same request doesn't cause extra side effects. In practice, interviewers care less about you reciting definitions and more about whether you'd pick ",[15,42217,42142],{}," for creating a resource versus ",[15,42220,42158],{}," for replacing one, since mixing these up is a very common mistake in real APIs.",[242,42223,42225],{"id":42224},"_2-what-is-the-difference-between-put-and-patch","2. What is the difference between PUT and PATCH?",[11,42227,42228,42230,42231,42234,42235,42237],{},[15,42229,42158],{}," replaces the ",[1511,42232,42233],{},"entire"," resource with the payload you send; anything you omit is treated as removed or reset to a default. ",[15,42236,42173],{}," only updates the fields you include, leaving the rest untouched.",[11,42239,42240,42241,195,42243,394,42246,42249,42250,42252,42253,834,42255,42257,42258,42260,42261,42263,42264,42266,42267,42269,42270,42272,42273,42275],{},"For example, if a user resource has ",[15,42242,5271],{},[15,42244,42245],{},"email",[15,42247,42248],{},"age",", sending a ",[15,42251,42158],{}," with only ",[15,42254,5271],{},[15,42256,42245],{}," could wipe out ",[15,42259,42248],{},". Sending the same data as a ",[15,42262,42173],{}," would leave ",[15,42265,42248],{}," exactly as it was. In short: ",[15,42268,42158],{}," is a full replace, ",[15,42271,42173],{}," is a partial edit. Many APIs implement both, but ",[15,42274,42173],{}," is the safer default when you only want to change one or two fields.",[242,42277,42279],{"id":42278},"_3-what-does-it-mean-for-an-http-method-to-be-idempotent-and-which-methods-are-idempotent","3. What does it mean for an HTTP method to be idempotent, and which methods are idempotent?",[11,42281,42282,42285],{},[10490,42283,42284],{},"Idempotent"," means calling the same request multiple times produces the same result as calling it once; the server ends up in the same state no matter how many times the client retries.",[11,42287,42288,195,42290,195,42292,195,42294,394,42297,42300,42301,42304,42305,42308,42309,42312,42313,42315,42316,42318,42319,42322,42323,42325],{},[15,42289,42126],{},[15,42291,42158],{},[15,42293,42188],{},[15,42295,42296],{},"HEAD",[15,42298,42299],{},"OPTIONS"," are idempotent. ",[15,42302,42303],{},"PUT /users/1"," with the same body always leaves user 1 in the same final state, and ",[15,42306,42307],{},"DELETE /users/1"," called twice just means the user is deleted (the second call may 404, but the ",[1511,42310,42311],{},"state"," doesn't change further). ",[15,42314,42142],{}," is generally ",[1511,42317,5608],{}," idempotent, since calling ",[15,42320,42321],{},"POST /orders"," twice typically creates two separate orders. This matters most for retry logic: it's safe to blindly retry an idempotent request after a network timeout, but retrying a ",[15,42324,42142],{}," without care can duplicate data.",[242,42327,42329],{"id":42328},"_4-what-is-the-difference-between-a-4xx-and-a-5xx-status-code-give-examples-of-each","4. What is the difference between a 4xx and a 5xx status code? Give examples of each.",[11,42331,42332,42335,42336,42339,42340,42335,42343,42346],{},[15,42333,42334],{},"4xx"," status codes mean the ",[1511,42337,42338],{},"client"," made a mistake (bad input, missing auth, requesting something that doesn't exist). ",[15,42341,42342],{},"5xx",[1511,42344,42345],{},"server"," failed to handle a valid request, even though the client did nothing wrong.",[4068,42348,42349,42362],{},[4071,42350,42351],{},[4074,42352,42353,42356,42359],{},[4077,42354,42355],{},"Range",[4077,42357,42358],{},"Meaning",[4077,42360,42361],{},"Common examples",[4090,42363,42364,42388],{},[4074,42365,42366,42370,42373],{},[4095,42367,42368],{},[15,42369,42334],{},[4095,42371,42372],{},"Client error",[4095,42374,42375,42378,42379,42381,42382,42384,42385,42387],{},[15,42376,42377],{},"400"," Bad Request, ",[15,42380,40308],{}," Unauthorized, ",[15,42383,32890],{}," Not Found, ",[15,42386,33517],{}," Unprocessable Entity",[4074,42389,42390,42394,42397],{},[4095,42391,42392],{},[15,42393,42342],{},[4095,42395,42396],{},"Server error",[4095,42398,42399,42401,42402,42405,42406,42409],{},[15,42400,9235],{}," Internal Server Error, ",[15,42403,42404],{},"502"," Bad Gateway, ",[15,42407,42408],{},"503"," Service Unavailable",[11,42411,42412,42413,42415,42416,42418],{},"This distinction is useful in debugging too: a spike in ",[15,42414,42334],{}," errors usually points to a client-side bug or bad documentation, while a spike in ",[15,42417,42342],{}," errors points to something broken on your infrastructure or code, like an unhandled exception or a downstream service timing out.",[242,42420,42422],{"id":42421},"_5-what-is-the-difference-between-401-unauthorized-and-403-forbidden","5. What is the difference between 401 Unauthorized and 403 Forbidden?",[11,42424,42425,42428,42429,42432,42433,42435],{},[15,42426,42427],{},"401 Unauthorized"," means the request has no valid credentials at all, or the ones provided are invalid or expired; the server doesn't know who you are. ",[15,42430,42431],{},"403 Forbidden"," means the server ",[1511,42434,38697],{}," know who you are, but you don't have permission to access that resource.",[11,42437,42438,42439,42441,42442,42444,42445,42447,42448,81],{},"A simple way to remember it: ",[15,42440,40308],{}," is \"please log in,\" ",[15,42443,33190],{}," is \"you're logged in, but you're not allowed here.\" For example, hitting an admin-only endpoint without a token returns ",[15,42446,40308],{},", but hitting it while logged in as a regular (non-admin) user returns ",[15,42449,33190],{},[242,42451,42453],{"id":42452},"_6-what-is-the-difference-between-a-301-and-a-302-redirect","6. What is the difference between a 301 and a 302 redirect?",[11,42455,42456,42459,42460,42463,42464,42467],{},[15,42457,42458],{},"301 Moved Permanently"," tells the client (and search engines) that a resource has permanently moved to a new URL; browsers and crawlers will update their references and cache the new location. ",[15,42461,42462],{},"302 Found"," (temporary redirect) says the resource is ",[1511,42465,42466],{},"currently"," at a different URL, but the original URL should still be used for future requests.",[11,42469,42470,42471,42474,42475,42478],{},"Using the wrong one has real consequences: a ",[15,42472,42473],{},"301"," on a URL that later changes back can leave search engines and caches pointing at the wrong place for a long time, while using ",[15,42476,42477],{},"302"," for something that's actually permanent means you lose SEO value that should have transferred to the new URL.",[242,42480,42482],{"id":42481},"_7-what-are-http-headers-and-whats-the-difference-between-request-headers-and-response-headers","7. What are HTTP headers, and what's the difference between request headers and response headers?",[11,42484,42485,42488],{},[10490,42486,42487],{},"Headers"," are key-value pairs sent alongside an HTTP request or response that carry metadata, separate from the actual body content. They describe things like content type, authentication, caching rules, and client information.",[11,42490,42491,42494,42495,42497,42498,42501,42502,42505,42506,42509,42510,42512,42513,42516,42517,42520,42521,42523],{},[10490,42492,42493],{},"Request headers"," are sent by the client to give the server context about the request, such as ",[15,42496,37894],{}," (credentials), ",[15,42499,42500],{},"Content-Type"," (format of the body being sent), and ",[15,42503,42504],{},"Accept"," (what response formats the client can handle). ",[10490,42507,42508],{},"Response headers"," are sent back by the server to describe the response, such as ",[15,42511,42500],{}," of the returned data, ",[15,42514,42515],{},"Set-Cookie",", and caching headers like ",[15,42518,42519],{},"Cache-Control",". Some headers, like ",[15,42522,42500],{},", appear on both sides but describe different things depending on direction.",[242,42525,42527],{"id":42526},"_8-what-is-cors-and-why-does-the-browser-enforce-it","8. What is CORS, and why does the browser enforce it?",[11,42529,42530,42533,42534,42537,42538,42541],{},[10490,42531,42532],{},"CORS"," (Cross-Origin Resource Sharing) is a browser security mechanism that controls whether a web page running on one origin (domain, protocol, and port) is allowed to make requests to a server on a ",[1511,42535,42536],{},"different"," origin. By default, browsers block cross-origin requests due to the ",[10490,42539,42540],{},"same-origin policy",", and CORS is the standard way for a server to explicitly relax that restriction.",[11,42543,42544,42545,42548],{},"The browser enforces this to protect users: without it, a malicious website could silently make authenticated requests to another site (like your bank) using cookies stored in your browser, and read the response. When a browser makes a cross-origin request, the server must respond with headers like ",[15,42546,42547],{},"Access-Control-Allow-Origin"," telling the browser which origins are permitted.",[83,42550,42554],{"className":42551,"code":42552,"language":42553,"meta":88,"style":88},"language-http shiki shiki-themes github-dark","Access-Control-Allow-Origin: https://example.com\nAccess-Control-Allow-Methods: GET, POST, PUT, DELETE\nAccess-Control-Allow-Headers: Content-Type, Authorization\n","http",[15,42555,42556,42561,42566],{"__ignoreMap":88},[92,42557,42558],{"class":94,"line":95},[92,42559,42560],{},"Access-Control-Allow-Origin: https://example.com\n",[92,42562,42563],{"class":94,"line":106},[92,42564,42565],{},"Access-Control-Allow-Methods: GET, POST, PUT, DELETE\n",[92,42567,42568],{"class":94,"line":113},[92,42569,42570],{},"Access-Control-Allow-Headers: Content-Type, Authorization\n",[11,42572,42573,42574,42577,42578,42580],{},"It's worth knowing that CORS is enforced by the ",[1511,42575,42576],{},"browser",", not the server; server-to-server requests and tools like ",[15,42579,11145],{}," ignore CORS entirely.",[242,42582,42584],{"id":42583},"_9-what-does-it-mean-for-http-to-be-a-stateless-protocol","9. What does it mean for HTTP to be a stateless protocol?",[11,42586,42587,42590],{},[10490,42588,42589],{},"Stateless"," means each HTTP request is handled independently; the server doesn't automatically remember anything about previous requests from the same client. Every request must carry all the information the server needs to process it, such as authentication tokens.",[11,42592,42593],{},"This is why things like login sessions require extra mechanisms, cookies, tokens, or server-side session stores, to simulate \"memory\" across requests. Statelessness is actually a deliberate design choice: it makes servers easier to scale horizontally, since any server in a pool can handle any request without needing to know what happened before.",[242,42595,42597],{"id":42596},"_10-what-is-the-difference-between-http11-http2-and-http3-at-a-high-level","10. What is the difference between HTTP/1.1, HTTP/2, and HTTP/3 at a high level?",[11,42599,42600],{},"Each version improves how requests and responses move over the network, without changing the core semantics (methods, status codes, headers stay conceptually the same).",[11,42602,42603,42606,42607,42610],{},[10490,42604,42605],{},"HTTP/1.1"," sends requests as plain text over a single connection per request at a time (with keep-alive to reuse the connection), which leads to ",[1511,42608,42609],{},"head-of-line blocking",": one slow request can delay the ones behind it, so browsers open multiple parallel connections as a workaround.",[11,42612,42613,42616,42617,42620],{},[10490,42614,42615],{},"HTTP/2"," introduced ",[1511,42618,42619],{},"multiplexing",", allowing many requests and responses to be interleaved over a single TCP connection, along with header compression and server push. This removed the need for multiple connections and made pages load faster, especially with many small assets.",[11,42622,42623,42626,42627,42630,42631,42633],{},[10490,42624,42625],{},"HTTP/3"," replaces the underlying transport, moving from TCP to ",[15,42628,42629],{},"QUIC"," (built on UDP). This fixes a subtler problem: in HTTP/2, if a single TCP packet is lost, ",[1511,42632,33765],{}," multiplexed streams stall waiting for retransmission. QUIC handles streams independently, so packet loss on one stream doesn't block the others, which matters a lot on flaky mobile networks.",[4068,42635,42636,42649],{},[4071,42637,42638],{},[4074,42639,42640,42643,42646],{},[4077,42641,42642],{},"Version",[4077,42644,42645],{},"Transport",[4077,42647,42648],{},"Key improvement",[4090,42650,42651,42661,42670],{},[4074,42652,42653,42655,42658],{},[4095,42654,42605],{},[4095,42656,42657],{},"TCP",[4095,42659,42660],{},"Simple, but one request at a time per connection",[4074,42662,42663,42665,42667],{},[4095,42664,42615],{},[4095,42666,42657],{},[4095,42668,42669],{},"Multiplexed streams, header compression",[4074,42671,42672,42674,42677],{},[4095,42673,42625],{},[4095,42675,42676],{},"QUIC (UDP)",[4095,42678,42679],{},"Avoids TCP-level head-of-line blocking",[242,42681,42683,42684,42686],{"id":42682},"_11-what-is-content-negotiation-and-how-does-the-accept-header-relate-to-it","11. What is content negotiation, and how does the ",[15,42685,42504],{}," header relate to it?",[11,42688,42689,42692],{},[10490,42690,42691],{},"Content negotiation"," is the process where a client and server agree on the best format to represent a resource, such as JSON versus XML, or English versus French. Instead of a server having one fixed format for every client, it can serve different representations based on what the client asks for.",[11,42694,42695,42696,42698,42699,42702,42703,42706],{},"The client signals its preference using the ",[15,42697,42504],{}," header (for format) and headers like ",[15,42700,42701],{},"Accept-Language"," (for language). The server reads these and responds accordingly, often falling back to a default if it can't satisfy the request, or returning ",[15,42704,42705],{},"406 Not Acceptable"," if it truly can't.",[83,42708,42710],{"className":42551,"code":42709,"language":42553,"meta":88,"style":88},"GET /users/42 HTTP/1.1\nAccept: application/json\nAccept-Language: en-US\n",[15,42711,42712,42717,42722],{"__ignoreMap":88},[92,42713,42714],{"class":94,"line":95},[92,42715,42716],{},"GET /users/42 HTTP/1.1\n",[92,42718,42719],{"class":94,"line":106},[92,42720,42721],{},"Accept: application/json\n",[92,42723,42724],{"class":94,"line":113},[92,42725,42726],{},"Accept-Language: en-US\n",[242,42728,42730,42731,195,42734,394,42737,32126],{"id":42729},"_12-what-are-cookies-used-for-on-the-backend-and-what-do-attributes-like-httponly-secure-and-samesite-do","12. What are cookies used for on the backend, and what do attributes like ",[15,42732,42733],{},"HttpOnly",[15,42735,42736],{},"Secure",[15,42738,42739],{},"SameSite",[11,42741,42742,42745],{},[10490,42743,42744],{},"Cookies"," are small pieces of data the server asks the browser to store and automatically send back on future requests to the same site. On the backend, they're commonly used for session identifiers, authentication tokens, and tracking user preferences, since HTTP itself is stateless.",[11,42747,42748],{},"A few attributes control how safely cookies behave:",[11016,42750,42751,42756,42761],{},[11019,42752,42753,42755],{},[15,42754,42733],{}," prevents JavaScript from reading the cookie, which protects against theft via cross-site scripting (XSS).",[11019,42757,42758,42760],{},[15,42759,42736],{}," ensures the cookie is only sent over HTTPS, not plain HTTP.",[11019,42762,42763,3559,42765,195,42768,1375,42771,42774],{},[15,42764,42739],{},[15,42766,42767],{},"Strict",[15,42769,42770],{},"Lax",[15,42772,42773],{},"None",") controls whether the cookie is sent on cross-site requests, which helps prevent cross-site request forgery (CSRF).",[11,42776,42777,42778,195,42780,394,42782,6339,42785,42787,42788,81],{},"A typical session cookie for a production app would set all three: ",[15,42779,42733],{},[15,42781,42736],{},[15,42783,42784],{},"SameSite=Lax",[15,42786,42767],{},", to minimize the attack surface. For a deeper comparison of cookies against browser storage options, see ",[23,42789,39268],{"href":39267},[242,42791,42793],{"id":42792},"_13-what-is-the-same-origin-policy","13. What is the same-origin policy?",[11,42795,1792,42796,42798],{},[10490,42797,42540],{}," is a browser security rule that restricts how a script loaded from one origin can interact with resources from a different origin. Two URLs share an origin only if they have the same protocol, domain, and port; changing any one of those makes it a different origin.",[11,42800,42801],{},"Without this policy, a script running on a malicious page could freely read data from other sites you're logged into, like your email or bank, using your existing browser session. It's the underlying reason CORS exists: CORS is essentially a controlled way for a server to opt out of the same-origin restriction for specific origins.",[242,42803,42805],{"id":42804},"_14-what-is-a-websocket-and-how-is-it-different-from-a-regular-http-request","14. What is a WebSocket, and how is it different from a regular HTTP request?",[11,42807,6686,42808,42811],{},[10490,42809,42810],{},"WebSocket"," is a persistent, full-duplex (two-way) connection between client and server, established by an initial HTTP handshake that then \"upgrades\" to the WebSocket protocol. Once open, either side can send messages at any time without starting a new request each time.",[11,42813,42814,42815,42817],{},"A regular HTTP request follows a strict request-response cycle: the client asks, the server answers, and the connection is typically closed or reused for the ",[1511,42816,6942],{}," separate request-response pair. This makes plain HTTP a poor fit for things that need real-time, ongoing communication, like chat apps, live notifications, or collaborative editing, since the client would otherwise have to keep polling the server for updates. WebSockets solve this by keeping one connection open so the server can push data to the client the moment it's available.",[39,42819,42821],{"id":42820},"api-design","API Design",[242,42823,42825],{"id":42824},"_15-what-makes-an-api-restful-what-are-the-core-rest-constraints","15. What makes an API \"RESTful\"? What are the core REST constraints?",[11,42827,42828,42831],{},[10490,42829,42830],{},"REST"," (Representational State Transfer) is an architectural style for designing networked APIs, built around a set of constraints rather than a strict protocol. An API is considered RESTful when it follows these principles, even though in practice most \"REST APIs\" only loosely follow all of them.",[11,42833,42834],{},"The core constraints are:",[11016,42836,42837,42843,42849,42855,42866,42872],{},[11019,42838,42839,42842],{},[10490,42840,42841],{},"Client-server separation",": the client and server evolve independently, communicating only through requests.",[11019,42844,42845,42848],{},[10490,42846,42847],{},"Statelessness",": each request contains everything needed to process it; the server holds no client session state between requests.",[11019,42850,42851,42854],{},[10490,42852,42853],{},"Cacheability",": responses should indicate whether they can be cached, to improve performance.",[11019,42856,42857,42860,42861,195,42863,42865],{},[10490,42858,42859],{},"Uniform interface",": resources are identified by URLs, manipulated through a consistent set of methods (",[15,42862,42126],{},[15,42864,42142],{},", etc.), and represented in a standard format like JSON.",[11019,42867,42868,42871],{},[10490,42869,42870],{},"Layered system",": the client shouldn't need to know whether it's talking directly to the server or through intermediaries like load balancers or caches.",[11019,42873,42874,42877],{},[10490,42875,42876],{},"Code on demand"," (optional): servers can optionally send executable code to the client.",[11,42879,42880,42881,42883],{},"In interviews, the practical expectation is usually simpler: can you design endpoints around ",[1511,42882,12549],{}," (nouns), use HTTP methods correctly, and keep requests stateless, rather than reciting the formal constraint list.",[242,42885,42887],{"id":42886},"_16-what-is-the-difference-between-resource-based-url-design-and-action-based-url-design-give-examples-of-good-vs-bad-rest-endpoint-naming","16. What is the difference between resource-based URL design and action-based URL design? Give examples of good vs bad REST endpoint naming.",[11,42889,42890,42893,42894,42897],{},[10490,42891,42892],{},"Resource-based"," design treats URLs as nouns representing things (resources), and uses HTTP methods to express the action. ",[10490,42895,42896],{},"Action-based"," design bakes the verb directly into the URL, which goes against REST conventions.",[4068,42899,42900,42910],{},[4071,42901,42902],{},[4074,42903,42904,42907],{},[4077,42905,42906],{},"Bad (action-based)",[4077,42908,42909],{},"Good (resource-based)",[4090,42911,42912,42924,42936,42948],{},[4074,42913,42914,42919],{},[4095,42915,42916],{},[15,42917,42918],{},"POST /createUser",[4095,42920,42921],{},[15,42922,42923],{},"POST /users",[4074,42925,42926,42931],{},[4095,42927,42928],{},[15,42929,42930],{},"GET /getUserOrders?id=5",[4095,42932,42933],{},[15,42934,42935],{},"GET /users/5/orders",[4074,42937,42938,42943],{},[4095,42939,42940],{},[15,42941,42942],{},"POST /deleteOrder/12",[4095,42944,42945],{},[15,42946,42947],{},"DELETE /orders/12",[4074,42949,42950,42955],{},[4095,42951,42952],{},[15,42953,42954],{},"POST /updateUserEmail",[4095,42956,42957],{},[15,42958,42959],{},"PATCH /users/5",[11,42961,42962],{},"The resource-based style is preferred because the URL stays stable and the HTTP method conveys the intent, which keeps the API predictable and consistent as it grows. It also means you don't end up with an ever-growing list of one-off endpoint names for every possible action.",[242,42964,42966],{"id":42965},"_17-how-do-you-version-an-api-and-what-are-the-tradeoffs-of-different-versioning-strategies-url-path-header-query-param","17. How do you version an API, and what are the tradeoffs of different versioning strategies (URL path, header, query param)?",[11,42968,42969,42972],{},[10490,42970,42971],{},"API versioning"," lets you change or break a contract without disrupting clients still relying on the old behavior. Since consumers of a public API can't all upgrade at the same time, some way of running multiple versions side by side is usually necessary.",[4068,42974,42975,42988],{},[4071,42976,42977],{},[4074,42978,42979,42982,42985],{},[4077,42980,42981],{},"Strategy",[4077,42983,42984],{},"Example",[4077,42986,42987],{},"Tradeoff",[4090,42989,42990,43003,43016,43029],{},[4074,42991,42992,42995,43000],{},[4095,42993,42994],{},"URL path",[4095,42996,42997],{},[15,42998,42999],{},"/v1/users",[4095,43001,43002],{},"Very visible and easy to route/cache, but \"pollutes\" the URL and implies the resource itself changed",[4074,43004,43005,43008,43013],{},[4095,43006,43007],{},"Custom header",[4095,43009,43010],{},[15,43011,43012],{},"Api-Version: 2",[4095,43014,43015],{},"Keeps URLs clean, but less discoverable and harder to test manually (e.g. in a browser)",[4074,43017,43018,43021,43026],{},[4095,43019,43020],{},"Query param",[4095,43022,43023],{},[15,43024,43025],{},"/users?version=2",[4095,43027,43028],{},"Simple to add, but easy to forget and doesn't play well with caching",[4074,43030,43031,43037,43042],{},[4095,43032,43033,43034,43036],{},"Media type (",[15,43035,42504],{}," header)",[4095,43038,43039],{},[15,43040,43041],{},"Accept: application/vnd.api.v2+json",[4095,43043,43044],{},"Follows content negotiation properly, but the least intuitive for most developers",[11,43046,43047,43048,43051],{},"URL path versioning is the most common in practice because it's explicit and simple to reason about, even though it's considered less \"pure REST\" than negotiating the version via headers. Whatever strategy you pick, the more important discipline is minimizing ",[1511,43049,43050],{},"how often"," you need a new version by preferring backward-compatible changes.",[242,43053,43055],{"id":43054},"_18-what-is-pagination-and-whats-the-difference-between-offset-based-and-cursor-based-pagination","18. What is pagination, and what's the difference between offset-based and cursor-based pagination?",[11,43057,43058,43060],{},[10490,43059,40988],{}," splits a large result set into smaller chunks (pages) so a single request doesn't return, say, a million rows at once.",[11,43062,43063,43066,43067,43070],{},[10490,43064,43065],{},"Offset-based"," pagination uses a page number or offset plus a limit, like ",[15,43068,43069],{},"GET /orders?offset=40&limit=20",". It's simple to implement and lets users jump to any page directly, but it has a real weakness: if rows are inserted or deleted while paging through results, items can be skipped or duplicated, and performance degrades on large offsets since the database still has to scan past all the skipped rows.",[11,43072,43073,43076,43077,43079,43080,43083],{},[10490,43074,43075],{},"Cursor-based"," pagination instead returns a pointer (cursor), often an encoded value based on the last item's ID or timestamp, and the next request asks for items ",[1511,43078,32990],{}," that cursor, like ",[15,43081,43082],{},"GET /orders?after=cursor_abc123&limit=20",". This stays consistent even as data changes and scales much better on large tables, but you lose the ability to jump directly to an arbitrary page. Cursor-based pagination is generally preferred for large, frequently-changing datasets and infinite-scroll style feeds.",[242,43085,43087],{"id":43086},"_19-what-is-rate-limiting-and-why-do-apis-implement-it","19. What is rate limiting, and why do APIs implement it?",[11,43089,43090,43092,43093,81],{},[10490,43091,40085],{}," restricts how many requests a client can make to an API within a given time window, for example 100 requests per minute per API key. When the limit is exceeded, the server typically responds with ",[15,43094,40218],{},[11,43096,43097,43098,834,43101,43104],{},"APIs implement it to protect their infrastructure from being overwhelmed (whether by legitimate traffic spikes, bugs like retry loops, or abuse), to keep the service fair across all consumers, and sometimes as part of a paid tiering model. Common strategies include fixed windows, sliding windows, and token bucket algorithms. Response headers like ",[15,43099,43100],{},"X-RateLimit-Remaining",[15,43102,43103],{},"Retry-After"," are often included so well-behaved clients know when to back off.",[242,43106,43108],{"id":43107},"_20-what-is-an-idempotency-key-and-why-is-it-important-for-apis-like-payment-processing","20. What is an idempotency key, and why is it important for APIs like payment processing?",[11,43110,26615,43111,43114],{},[10490,43112,43113],{},"idempotency key"," is a unique value (usually a client-generated UUID) that the client attaches to a request so the server can recognize and safely ignore duplicate submissions of the same operation.",[11,43116,43117,43118,43120],{},"This matters most for non-idempotent methods like ",[15,43119,42142],{},". Imagine a client sends a payment request, the network times out before the response arrives, and the client retries. Without an idempotency key, that retry could charge the customer twice. With one, the server checks if it has already processed that exact key; if so, it returns the original result instead of processing the payment again.",[83,43122,43124],{"className":42551,"code":43123,"language":42553,"meta":88,"style":88},"POST /payments HTTP/1.1\nIdempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7\nContent-Type: application/json\n\n{ \"amount\": 4999, \"currency\": \"usd\" }\n",[15,43125,43126,43131,43136,43141,43145],{"__ignoreMap":88},[92,43127,43128],{"class":94,"line":95},[92,43129,43130],{},"POST /payments HTTP/1.1\n",[92,43132,43133],{"class":94,"line":106},[92,43134,43135],{},"Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7\n",[92,43137,43138],{"class":94,"line":113},[92,43139,43140],{},"Content-Type: application/json\n",[92,43142,43143],{"class":94,"line":138},[92,43144,110],{"emptyLinePlaceholder":109},[92,43146,43147],{"class":94,"line":143},[92,43148,43149],{},"{ \"amount\": 4999, \"currency\": \"usd\" }\n",[242,43151,43153],{"id":43152},"_21-what-is-the-difference-between-rest-and-graphql-at-a-conceptual-level","21. What is the difference between REST and GraphQL at a conceptual level?",[11,43155,43156,43158,43159,43162,43163,43166],{},[10490,43157,42830],{}," exposes multiple fixed endpoints, each returning a predetermined shape of data for a resource. ",[10490,43160,43161],{},"GraphQL"," exposes a ",[1511,43164,43165],{},"single"," endpoint where the client sends a query describing exactly the fields it wants, and the server returns data matching that shape, nothing more, nothing less.",[11,43168,43169,43170,43173,43174,43177],{},"This difference solves two common REST pain points: ",[1511,43171,43172],{},"over-fetching"," (getting fields you don't need, wasting bandwidth) and ",[1511,43175,43176],{},"under-fetching"," (needing to call multiple endpoints to assemble the data a screen actually needs, like fetching a user, then their orders, then each order's items separately). GraphQL lets a client ask for a user along with specific nested fields from orders and items in one request.",[83,43179,43182],{"className":43180,"code":43181,"language":36619,"meta":88},[40272],"query {\n  user(id: 5) {\n    name\n    orders {\n      id\n      total\n    }\n  }\n}\n",[15,43183,43181],{"__ignoreMap":88},[11,43185,43186,43187,43190,43191,43195],{},"The tradeoff is that GraphQL pushes more complexity onto the server (query cost analysis, avoiding N+1 queries under the hood, custom caching) and loses some of REST's simplicity, like relying on standard HTTP caching by URL. Neither is strictly \"better\"; REST tends to be simpler for straightforward CRUD APIs, while GraphQL shines when clients have very different, evolving data needs (like a mobile app versus a web dashboard). Both are also younger than ",[10490,43188,43189],{},"SOAP",", the XML-based protocol REST largely replaced for public APIs but which still runs a lot of enterprise and banking infrastructure; the ",[23,43192,43194],{"href":43193},"/post/soap-api","SOAP API"," article covers why it hasn't gone away.",[242,43197,43199],{"id":43198},"_22-what-is-hateoas","22. What is HATEOAS?",[11,43201,43202,43205],{},[10490,43203,43204],{},"HATEOAS"," (Hypermedia as the Engine of Application State) is a REST constraint where API responses include links describing what actions or related resources are available next, similar to how clicking through a website works without knowing URLs in advance.",[11,43207,43208,43209,6339,43212,43215],{},"For example, a response for an order might include links to ",[15,43210,43211],{},"cancel",[15,43213,43214],{},"pay"," actions directly in the payload, rather than the client having to hardcode those URLs based on documentation. In theory this lets clients navigate an API dynamically as it evolves; in practice, very few real-world APIs implement it fully, since it adds complexity that most teams don't find worth the payoff. It's still a common interview topic because it's part of the \"official\" REST definition.",[242,43217,43219],{"id":43218},"_23-how-should-an-api-communicate-errors-to-consumers-what-makes-a-good-error-response","23. How should an API communicate errors to consumers? What makes a good error response?",[11,43221,43222],{},"A good error response uses the right HTTP status code as the first signal, then includes a structured body with enough detail for the client to understand and, ideally, act on the problem, without leaking internal implementation details like stack traces.",[11,43224,43225],{},"A useful error response usually includes: a machine-readable error code (for programmatic handling), a human-readable message (for logs or display), and, for validation errors, which specific fields failed and why.",[83,43227,43229],{"className":14186,"code":43228,"language":9672,"meta":88,"style":88},"{\n  \"error\": {\n    \"code\": \"VALIDATION_FAILED\",\n    \"message\": \"One or more fields are invalid\",\n    \"details\": [\n      { \"field\": \"email\", \"issue\": \"must be a valid email address\" }\n    ]\n  }\n}\n",[15,43230,43231,43235,43242,43254,43265,43272,43296,43301,43306],{"__ignoreMap":88},[92,43232,43233],{"class":94,"line":95},[92,43234,11212],{"class":119},[92,43236,43237,43240],{"class":94,"line":106},[92,43238,43239],{"class":102},"  \"error\"",[92,43241,40337],{"class":119},[92,43243,43244,43247,43249,43252],{"class":94,"line":113},[92,43245,43246],{"class":102},"    \"code\"",[92,43248,5263],{"class":119},[92,43250,43251],{"class":171},"\"VALIDATION_FAILED\"",[92,43253,4772],{"class":119},[92,43255,43256,43258,43260,43263],{"class":94,"line":138},[92,43257,40322],{"class":102},[92,43259,5263],{"class":119},[92,43261,43262],{"class":171},"\"One or more fields are invalid\"",[92,43264,4772],{"class":119},[92,43266,43267,43270],{"class":94,"line":143},[92,43268,43269],{"class":102},"    \"details\"",[92,43271,14233],{"class":119},[92,43273,43274,43277,43280,43282,43284,43286,43289,43291,43294],{"class":94,"line":149},[92,43275,43276],{"class":119},"      { ",[92,43278,43279],{"class":102},"\"field\"",[92,43281,5263],{"class":119},[92,43283,33963],{"class":171},[92,43285,195],{"class":119},[92,43287,43288],{"class":102},"\"issue\"",[92,43290,5263],{"class":119},[92,43292,43293],{"class":171},"\"must be a valid email address\"",[92,43295,4506],{"class":119},[92,43297,43298],{"class":94,"line":155},[92,43299,43300],{"class":119},"    ]\n",[92,43302,43303],{"class":94,"line":161},[92,43304,43305],{"class":119},"  }\n",[92,43307,43308],{"class":94,"line":166},[92,43309,4711],{"class":119},[11,43311,43312],{},"Consistency matters a lot here: if every endpoint formats errors differently, client code ends up littered with special cases. Keeping one consistent error shape across the whole API makes it much easier for consumers to write generic error-handling logic.",[242,43314,43316],{"id":43315},"_24-what-is-an-api-contract-eg-via-openapiswagger-and-why-do-teams-maintain-one","24. What is an API contract (e.g. via OpenAPI/Swagger), and why do teams maintain one?",[11,43318,26615,43319,43322,43323,43326],{},[10490,43320,43321],{},"API contract"," is a formal, machine-readable description of an API's endpoints, request/response shapes, status codes, and authentication requirements, often written using a spec like ",[15,43324,43325],{},"OpenAPI"," (formerly Swagger).",[11,43328,43329],{},"Teams maintain one because it acts as a single source of truth that both the backend team and any API consumers (frontend, mobile, third-party partners) can rely on. Practical benefits include auto-generated documentation, auto-generated client SDKs, mock servers for frontend developers to build against before the backend is finished, and automated contract tests that catch accidental breaking changes before they ship.",[242,43331,43333],{"id":43332},"_25-what-is-the-difference-between-a-webhook-and-polling","25. What is the difference between a webhook and polling?",[11,43335,43336,43339,43340,43343,43344,43347],{},[10490,43337,43338],{},"Polling"," means the client repeatedly asks the server \"has anything changed?\" at fixed intervals, whether or not anything actually happened. ",[10490,43341,43342],{},"Webhooks"," flip this around: the client registers a URL with the server ahead of time, and the server calls ",[1511,43345,43346],{},"that"," URL to push data the moment an event occurs.",[11,43349,43350],{},"Polling is simple to implement but wastes resources on both sides, especially if changes are rare, and introduces delay equal to the polling interval. Webhooks are far more efficient and near-instant, but they add complexity: the receiving server needs a publicly reachable endpoint, must handle retries if delivery fails, and should verify the request actually came from the expected sender (commonly via a signature header). A common real-world example is a payment provider sending a webhook the moment a payment succeeds, instead of your server repeatedly asking \"is this payment done yet?\"",[242,43352,43354],{"id":43353},"_26-whats-the-difference-between-a-backward-compatible-api-change-and-a-breaking-change-give-examples-of-each","26. What's the difference between a backward-compatible API change and a breaking change? Give examples of each.",[11,43356,6686,43357,43360,43361,43364],{},[10490,43358,43359],{},"backward-compatible"," change is one that existing clients can safely ignore; their code keeps working without any modification. A ",[10490,43362,43363],{},"breaking change"," alters the contract in a way that existing client code can no longer rely on, causing errors or incorrect behavior.",[11,43366,43367],{},"Backward-compatible examples: adding a new optional field to a response, adding a new endpoint, adding a new optional query parameter, making a previously required field optional.",[11,43369,43370],{},"Breaking examples: removing or renaming a field, changing a field's data type (e.g. string to number), changing a status code for an existing scenario, making a previously optional parameter required, or changing the meaning of an existing field without renaming it.",[11,43372,43373],{},"The general rule of thumb: additive changes are usually safe, while removing, renaming, or changing the meaning or type of anything is usually breaking. This is exactly why API versioning exists, to introduce breaking changes without forcing every consumer to upgrade at once.",[39,43375,43377],{"id":43376},"relational-databases","Relational Databases",[11,43379,43380,43381,43383],{},"If any of the fundamentals below feel shaky, the ",[23,43382,34192],{"href":34191}," guide covers RDBMS basics, keys, joins, and schema design in more depth than an interview-prep answer can.",[242,43385,43387],{"id":43386},"_27-what-is-normalization-and-what-problem-does-it-solve","27. What is normalization, and what problem does it solve?",[11,43389,43390,43393],{},[10490,43391,43392],{},"Normalization"," is the process of organizing a database's tables and columns to reduce redundant data and avoid certain types of inconsistency. It works by breaking data into smaller, related tables connected through foreign keys, instead of repeating the same information across many rows.",[11,43395,43396,43397,43400,43401,43404,43405,43408],{},"Without normalization, if a customer's address were duplicated in every one of their orders and it changed, you'd need to update it in every row, and missing even one would leave the data inconsistent. Normalization solves this by storing the address once in a ",[15,43398,43399],{},"customers"," table and referencing it by ID from ",[15,43402,43403],{},"orders",". The tradeoff is that reading normalized data often requires joining multiple tables, which is where ",[10490,43406,43407],{},"denormalization"," sometimes comes back into play for performance.",[242,43410,43412],{"id":43411},"_28-can-you-explain-the-first-three-normal-forms-1nf-2nf-3nf-in-simple-terms","28. Can you explain the first three normal forms (1NF, 2NF, 3NF) in simple terms?",[11,43414,43415],{},"Each normal form builds on the one before it, progressively removing specific kinds of redundancy.",[11,43417,43418,43421,43422,43425,43426,43429],{},[10490,43419,43420],{},"1NF (First Normal Form)",": every column holds a single, atomic value, not a list or a set of values crammed into one field. A ",[15,43423,43424],{},"phone_numbers"," column containing ",[15,43427,43428],{},"\"555-1234, 555-5678\""," violates 1NF; it should be split into a separate table where each row is one phone number linked to the customer.",[11,43431,43432,43435,43436,43438,43439,43442,43443,43446,43447,43450,43451,43454,43455,43458],{},[10490,43433,43434],{},"2NF (Second Normal Form)",": builds on 1NF, and requires that every non-key column depends on the ",[1511,43437,42233],{}," primary key, not just part of it. This only really applies to tables with a composite (multi-column) primary key. For example, in an ",[15,43440,43441],{},"order_items"," table keyed on ",[15,43444,43445],{},"(order_id, product_id)",", a column like ",[15,43448,43449],{},"product_name"," depends only on ",[15,43452,43453],{},"product_id",", not the full key, so it violates 2NF and should live in a separate ",[15,43456,43457],{},"products"," table instead.",[11,43460,43461,43464,43465,43468,43469,43472,43473,195,43476,394,43479,43482,43483,43485,43486,43488,43489,43491,43492,43494,43495,34254],{},[10490,43462,43463],{},"3NF (Third Normal Form)",": builds on 2NF, and requires that non-key columns depend ",[1511,43466,43467],{},"only"," on the primary key, not on other non-key columns. If a ",[15,43470,43471],{},"students"," table has ",[15,43474,43475],{},"student_id",[15,43477,43478],{},"department_id",[15,43480,43481],{},"department_name",", then ",[15,43484,43481],{}," depends on ",[15,43487,43478],{}," rather than directly on ",[15,43490,43475],{},", which violates 3NF; ",[15,43493,43481],{}," should move into its own ",[15,43496,43497],{},"departments",[11,43499,43500],{},"In short: 1NF is about atomic values, 2NF is about full key dependency, and 3NF is about removing dependencies between non-key columns.",[242,43502,43504],{"id":43503},"_29-what-is-denormalization-and-when-would-you-intentionally-use-it","29. What is denormalization, and when would you intentionally use it?",[11,43506,43507,43510],{},[10490,43508,43509],{},"Denormalization"," is the deliberate act of introducing redundancy back into a database, usually by duplicating data or merging tables, in order to reduce the number of joins needed for common read queries.",[11,43512,43513,43514,43517,43518,43520],{},"It's a tradeoff: you gain faster reads at the cost of extra storage and more complex writes, since now you have to keep the duplicated data in sync in multiple places. It's commonly used for reporting/analytics tables, caching computed aggregates (like storing a ",[15,43515,43516],{},"total_reviews"," count directly on a ",[15,43519,43457],{}," row instead of counting them every time), or high-read, low-write systems where query speed matters more than storage efficiency.",[242,43522,43524],{"id":43523},"_30-what-is-the-difference-between-a-primary-key-a-foreign-key-and-a-unique-key","30. What is the difference between a primary key, a foreign key, and a unique key?",[11,43526,6686,43527,43529,43530,43533],{},[10490,43528,35345],{}," uniquely identifies each row in a table; a table can have only one, it cannot contain ",[15,43531,43532],{},"NULL",", and it's typically used to link to other tables.",[11,43535,6686,43536,43538,43539,43542,43543,43546,43547,43550],{},[10490,43537,36733],{}," is a column (or set of columns) in one table that references the primary key of another table, enforcing that the referenced value actually exists there. This is how relational databases maintain ",[10490,43540,43541],{},"referential integrity",", for example ensuring an ",[15,43544,43545],{},"order"," can't reference a ",[15,43548,43549],{},"customer_id"," that doesn't exist.",[11,43552,6686,43553,43556,43557,43559,43560,43562,43563,43565],{},[10490,43554,43555],{},"unique key"," enforces that all values in a column are distinct, just like a primary key, but a table can have several unique keys, and (unlike a primary key) unique columns can typically allow one ",[15,43558,43532],{}," value. A good example is an ",[15,43561,42245],{}," column: it's a natural fit for a unique key, but ",[15,43564,28803],{}," remains the primary key.",[242,43567,43569],{"id":43568},"_31-what-is-a-database-index-and-how-does-it-speed-up-queries","31. What is a database index, and how does it speed up queries?",[11,43571,26615,43572,43574,43575,43578],{},[10490,43573,33274],{}," is a separate data structure (commonly a ",[15,43576,43577],{},"B-tree",") that the database maintains alongside a table, allowing it to look up rows matching a condition without scanning every row.",[11,43580,43581,43582,43585,43586,43589,43590,43592,43593,43596,43597,43600,43601,43604],{},"Without an index, a query like ",[15,43583,43584],{},"SELECT * FROM users WHERE email = 'a@b.com'"," has to check every row in the table (a ",[1511,43587,43588],{},"full table scan","), which gets slower as the table grows. With an index on ",[15,43591,42245],{},", the database can jump almost directly to the matching row, similar to using the index at the back of a book instead of reading every page. Indexes dramatically speed up ",[15,43594,43595],{},"WHERE"," filters, ",[15,43598,43599],{},"JOIN"," conditions, and ",[15,43602,43603],{},"ORDER BY"," clauses on the indexed columns, but they aren't free (see the next question).",[242,43606,43608],{"id":43607},"_32-what-is-the-tradeoff-of-adding-too-many-indexes-to-a-table","32. What is the tradeoff of adding too many indexes to a table?",[11,43610,43611,43612,195,43615,1375,43618,43620],{},"Indexes speed up reads, but every index has to be updated on every ",[15,43613,43614],{},"INSERT",[15,43616,43617],{},"UPDATE",[15,43619,42188],{},", so more indexes mean slower writes. They also consume additional disk space, sometimes significantly, since each index is essentially its own copy of the indexed columns in a different structure.",[11,43622,43623,43624,195,43626,1375,43628,43630],{},"The practical guideline is to index columns that are frequently used in ",[15,43625,43595],{},[15,43627,43599],{},[15,43629,43603],{}," clauses, and avoid indexing columns that are rarely queried or that change very often, since those indexes add write overhead without much read benefit in return.",[242,43632,43634],{"id":43633},"_33-what-is-the-difference-between-a-clustered-index-and-a-non-clustered-index","33. What is the difference between a clustered index and a non-clustered index?",[11,43636,6686,43637,43640,43641,43644],{},[10490,43638,43639],{},"clustered index"," determines the ",[1511,43642,43643],{},"physical"," order in which rows are actually stored on disk; because of this, a table can have only one clustered index (often the primary key by default). Looking up a row via the clustered index means the data is found directly at that location.",[11,43646,6686,43647,43650],{},[10490,43648,43649],{},"non-clustered index"," is a separate structure that stores the indexed column's values along with a pointer (or reference) back to the actual row's location. A table can have many non-clustered indexes. Looking up via a non-clustered index typically means finding the pointer first, then following it to fetch the actual row, an extra step compared to a clustered index, though still far faster than a full scan. A simple analogy: a clustered index is like a phone book sorted by last name (the data itself is in that order), while a non-clustered index is like an index at the back of a textbook pointing you to a page number.",[242,43652,43654],{"id":43653},"_34-what-are-the-different-types-of-sql-joins-inner-left-right-full","34. What are the different types of SQL joins (INNER, LEFT, RIGHT, FULL)?",[11,43656,6686,43657,43660],{},[10490,43658,43659],{},"join"," combines rows from two or more tables based on a related column. Which rows survive the combination depends on the join type.",[4068,43662,43663,43672],{},[4071,43664,43665],{},[4074,43666,43667,43669],{},[4077,43668,25410],{},[4077,43670,43671],{},"Returns",[4090,43673,43674,43684,43697,43709],{},[4074,43675,43676,43681],{},[4095,43677,43678],{},[15,43679,43680],{},"INNER JOIN",[4095,43682,43683],{},"Only rows with matches in both tables",[4074,43685,43686,43691],{},[4095,43687,43688],{},[15,43689,43690],{},"LEFT JOIN",[4095,43692,43693,43694,43696],{},"All rows from the left table, matched rows from the right (or ",[15,43695,43532],{}," if no match)",[4074,43698,43699,43704],{},[4095,43700,43701],{},[15,43702,43703],{},"RIGHT JOIN",[4095,43705,43706,43707,43696],{},"All rows from the right table, matched rows from the left (or ",[15,43708,43532],{},[4074,43710,43711,43716],{},[4095,43712,43713],{},[15,43714,43715],{},"FULL JOIN",[4095,43717,43718,43719,43721],{},"All rows from both tables, ",[15,43720,43532],{}," where there's no match on either side",[83,43723,43727],{"className":43724,"code":43725,"language":43726,"meta":88,"style":88},"language-sql shiki shiki-themes github-dark","SELECT orders.id, customers.name\nFROM orders\nLEFT JOIN customers ON orders.customer_id = customers.id;\n","sql",[15,43728,43729,43750,43758],{"__ignoreMap":88},[92,43730,43731,43734,43737,43739,43741,43743,43745,43747],{"class":94,"line":95},[92,43732,43733],{"class":98},"SELECT",[92,43735,43736],{"class":102}," orders",[92,43738,81],{"class":119},[92,43740,28803],{"class":102},[92,43742,195],{"class":119},[92,43744,43399],{"class":102},[92,43746,81],{"class":119},[92,43748,43749],{"class":102},"name\n",[92,43751,43752,43755],{"class":94,"line":106},[92,43753,43754],{"class":98},"FROM",[92,43756,43757],{"class":119}," orders\n",[92,43759,43760,43762,43765,43768,43770,43772,43774,43776,43779,43781,43783],{"class":94,"line":113},[92,43761,43690],{"class":98},[92,43763,43764],{"class":119}," customers ",[92,43766,43767],{"class":98},"ON",[92,43769,43736],{"class":102},[92,43771,81],{"class":119},[92,43773,43549],{"class":102},[92,43775,853],{"class":98},[92,43777,43778],{"class":102}," customers",[92,43780,81],{"class":119},[92,43782,28803],{"class":102},[92,43784,229],{"class":119},[11,43786,43787,43788,43790,43791,43794,43795,43797,43798,43800,43801,43803,43804,81],{},"This ",[15,43789,43690],{}," example returns every order, even ones where the linked customer record is somehow missing, with ",[15,43792,43793],{},"customers.name"," showing as ",[15,43796,43532],{}," in that case. ",[15,43799,43680],{}," is the most commonly used in practice, while ",[15,43802,43703],{}," is rarely used since it's equivalent to swapping the table order and using ",[15,43805,43690],{},[242,43807,43809],{"id":43808},"_35-what-is-a-database-transaction-and-what-does-acid-stand-for","35. What is a database transaction, and what does ACID stand for?",[11,43811,6686,43812,43814],{},[10490,43813,36927],{}," groups multiple database operations into a single unit that either all succeed together or all fail together; there's no in-between state where only some of them took effect. For example, transferring money between two bank accounts involves debiting one account and crediting another, and a transaction ensures both happen, or neither does.",[11,43816,43817,43820],{},[10490,43818,43819],{},"ACID"," describes the guarantees a transaction should provide:",[11016,43822,43823,43829,43835,43841],{},[11019,43824,43825,43828],{},[10490,43826,43827],{},"Atomicity",": all operations in the transaction succeed, or none of them do; a partial failure rolls everything back.",[11019,43830,43831,43834],{},[10490,43832,43833],{},"Consistency",": a transaction takes the database from one valid state to another, never violating defined rules like constraints or foreign keys.",[11019,43836,43837,43840],{},[10490,43838,43839],{},"Isolation",": concurrent transactions don't interfere with each other in ways that produce incorrect results, as if transactions ran one at a time (the exact degree of this is controlled by isolation levels).",[11019,43842,43843,43846],{},[10490,43844,43845],{},"Durability",": once a transaction commits, its changes survive even a crash immediately afterward, typically because they've been written to persistent storage.",[83,43848,43850],{"className":43724,"code":43849,"language":43726,"meta":88,"style":88},"BEGIN;\nUPDATE accounts SET balance = balance - 100 WHERE id = 1;\nUPDATE accounts SET balance = balance + 100 WHERE id = 2;\nCOMMIT;\n",[15,43851,43852,43859,43892,43920],{"__ignoreMap":88},[92,43853,43854,43857],{"class":94,"line":95},[92,43855,43856],{"class":98},"BEGIN",[92,43858,229],{"class":119},[92,43860,43861,43863,43866,43869,43872,43874,43876,43878,43880,43883,43886,43888,43890],{"class":94,"line":106},[92,43862,43617],{"class":98},[92,43864,43865],{"class":119}," accounts ",[92,43867,43868],{"class":98},"SET",[92,43870,43871],{"class":119}," balance ",[92,43873,126],{"class":98},[92,43875,43871],{"class":119},[92,43877,1966],{"class":98},[92,43879,8302],{"class":102},[92,43881,43882],{"class":98}," WHERE",[92,43884,43885],{"class":119}," id ",[92,43887,126],{"class":98},[92,43889,1849],{"class":102},[92,43891,229],{"class":119},[92,43893,43894,43896,43898,43900,43902,43904,43906,43908,43910,43912,43914,43916,43918],{"class":94,"line":113},[92,43895,43617],{"class":98},[92,43897,43865],{"class":119},[92,43899,43868],{"class":98},[92,43901,43871],{"class":119},[92,43903,126],{"class":98},[92,43905,43871],{"class":119},[92,43907,1795],{"class":98},[92,43909,8302],{"class":102},[92,43911,43882],{"class":98},[92,43913,43885],{"class":119},[92,43915,126],{"class":98},[92,43917,1225],{"class":102},[92,43919,229],{"class":119},[92,43921,43922,43925],{"class":94,"line":138},[92,43923,43924],{"class":98},"COMMIT",[92,43926,229],{"class":119},[11,43928,43929,43930,43932],{},"If the second ",[15,43931,43617],{}," fails for any reason, atomicity guarantees the first one is rolled back too, so money doesn't vanish from account 1 without appearing in account 2.",[242,43934,43936],{"id":43935},"_36-what-are-database-transaction-isolation-levels-and-what-problem-does-each-one-solve","36. What are database transaction isolation levels, and what problem does each one solve?",[11,43938,43939,43942],{},[10490,43940,43941],{},"Isolation levels"," control how much one transaction is allowed to \"see\" the in-progress, uncommitted work of another concurrent transaction. Stricter isolation prevents more anomalies but generally costs more performance, since the database has to do more locking or version-checking.",[4068,43944,43945,43958],{},[4071,43946,43947],{},[4074,43948,43949,43952,43955],{},[4077,43950,43951],{},"Isolation level",[4077,43953,43954],{},"Prevents",[4077,43956,43957],{},"Still allows",[4090,43959,43960,43971,43982,43993],{},[4074,43961,43962,43965,43968],{},[4095,43963,43964],{},"Read Uncommitted",[4095,43966,43967],{},"Nothing",[4095,43969,43970],{},"Dirty reads, non-repeatable reads, phantom reads",[4074,43972,43973,43976,43979],{},[4095,43974,43975],{},"Read Committed",[4095,43977,43978],{},"Dirty reads",[4095,43980,43981],{},"Non-repeatable reads, phantom reads",[4074,43983,43984,43987,43990],{},[4095,43985,43986],{},"Repeatable Read",[4095,43988,43989],{},"Dirty reads, non-repeatable reads",[4095,43991,43992],{},"Phantom reads (mostly, depends on engine)",[4074,43994,43995,43998,44001],{},[4095,43996,43997],{},"Serializable",[4095,43999,44000],{},"All of the above",[4095,44002,44003],{},"Nothing (transactions behave as if run one at a time)",[11,44005,44006],{},"The anomalies being prevented are worth knowing in plain terms:",[11016,44008,44009,44015,44021],{},[11019,44010,6686,44011,44014],{},[10490,44012,44013],{},"dirty read"," happens when a transaction reads data that another transaction has written but not yet committed; if that other transaction rolls back, you've read data that never actually existed.",[11019,44016,6686,44017,44020],{},[10490,44018,44019],{},"non-repeatable read"," happens when a transaction reads the same row twice and gets different values, because another transaction updated and committed a change in between.",[11019,44022,6686,44023,44026,44027,44030],{},[10490,44024,44025],{},"phantom read"," happens when a transaction re-runs the same query and gets a ",[1511,44028,44029],{},"different set of rows",", because another transaction inserted or deleted rows matching that query in between.",[11,44032,44033,44035,44036,44038],{},[15,44034,43975],{}," is the default in many databases (like PostgreSQL) because it offers a reasonable balance; ",[15,44037,43997],{}," gives the strongest guarantees but can hurt throughput under heavy concurrent load, so it's typically reserved for operations where correctness (like financial calculations) matters more than raw speed.",[242,44040,44042],{"id":44041},"_37-what-is-a-deadlock-in-a-database-and-how-can-it-be-avoided","37. What is a deadlock in a database, and how can it be avoided?",[11,44044,6686,44045,44048],{},[10490,44046,44047],{},"deadlock"," occurs when two (or more) transactions are each waiting for a lock the other one holds, so neither can proceed; transaction A holds a lock that B needs, while B holds a lock that A needs. Most databases detect this situation and forcibly abort one of the transactions (the \"victim\") so the other can continue.",[11,44050,44051],{},"Deadlocks can be reduced by always acquiring locks in a consistent order across your codebase (e.g. always lock the lower-ID row first), keeping transactions short so locks aren't held longer than necessary, and avoiding unnecessary locking of rows the transaction doesn't actually need to modify. When a deadlock does occur, the application should catch the resulting error and retry the transaction.",[242,44053,44055],{"id":44054},"_38-what-is-the-n1-query-problem-and-how-do-you-fix-it","38. What is the N+1 query problem, and how do you fix it?",[11,44057,1792,44058,44061,44062,44065,44066,44069],{},[10490,44059,44060],{},"N+1 query problem"," happens when code runs one query to fetch a list of records, then runs an ",[1511,44063,44064],{},"additional"," query for each individual record to fetch related data, resulting in ",[15,44067,44068],{},"1 + N"," total queries instead of just one or two efficient ones.",[83,44071,44074],{"className":44072,"code":44073,"language":36619,"meta":88},[40272],"orders = SELECT * FROM orders          -- 1 query, returns N orders\nfor order in orders:\n    SELECT * FROM customers WHERE id = order.customer_id  -- N queries\n",[15,44075,44073],{"__ignoreMap":88},[11,44077,44078,44079,44081,44082,44085,44086,81],{},"If there are 100 orders, that's 101 round trips to the database instead of 1 or 2, which adds significant, often invisible, latency as the dataset grows. The fix is usually to fetch the related data upfront using a ",[15,44080,43599],{},", or to batch the lookups with a single query using ",[15,44083,44084],{},"WHERE id IN (...)"," across all the needed IDs, instead of querying per row in a loop. Many ORMs offer \"eager loading\" features specifically to avoid this pattern; for a concrete example of how this looks in Laravel's Eloquent, see the ",[23,44087,26],{"href":25},[242,44089,44091],{"id":44090},"_39-what-is-connection-pooling-and-why-does-it-matter","39. What is connection pooling, and why does it matter?",[11,44093,44094,44095,44098],{},"Opening a new database connection is relatively expensive; it involves a network handshake, authentication, and setting up session resources on the database server. ",[10490,44096,44097],{},"Connection pooling"," solves this by keeping a set of already-open connections ready to be reused, instead of opening and closing a new one for every single query.",[11,44100,44101],{},"When the application needs to run a query, it borrows a connection from the pool, uses it, and returns it when done, rather than paying the setup cost each time. This matters a lot under load: without pooling, a busy application could overwhelm the database with connection setup overhead alone, or hit the database's maximum connection limit and start failing requests.",[242,44103,44105],{"id":44104},"_40-what-is-database-replication-and-whats-the-difference-between-synchronous-and-asynchronous-replication","40. What is database replication, and what's the difference between synchronous and asynchronous replication?",[11,44107,44108,44111,44112,44115,44116,44119],{},[10490,44109,44110],{},"Replication"," is the process of copying data from one database (the ",[10490,44113,44114],{},"primary",", or leader) to one or more other databases (",[10490,44117,44118],{},"replicas",", or followers), so the same data exists in multiple places. It's used for high availability (a replica can take over if the primary fails), read scaling (reads can be spread across replicas), and disaster recovery.",[11,44121,14599,44122,44125],{},[10490,44123,44124],{},"synchronous replication",", the primary waits for at least one replica to confirm it has received and applied the write before telling the client the write succeeded. This guarantees the replica is always up to date, but it adds latency to every write and means the primary can be blocked if a replica is slow or unreachable.",[11,44127,14599,44128,44131],{},[10490,44129,44130],{},"asynchronous replication",", the primary confirms the write to the client immediately and sends the change to replicas in the background. This keeps writes fast, but there's a small window where a replica lags behind the primary, and if the primary fails before replicating a change, that write could be lost. Most systems default to asynchronous replication for performance, and accept eventual consistency on reads from replicas as the tradeoff.",[11,44133,44134],{},[3108,44135],{"alt":44136,"src":44137},"Primary-replica database replication diagram","/post-images/top-111-backend-interview-questions/database-replication-diagram.png",[242,44139,44141],{"id":44140},"_41-what-is-database-sharding-and-how-is-it-different-from-replication","41. What is database sharding, and how is it different from replication?",[11,44143,44144,44147,44148,44151,44152,44155,44156,44158],{},[10490,44145,44146],{},"Sharding"," (also called horizontal partitioning) splits a single logical database into multiple smaller, independent databases (",[10490,44149,44150],{},"shards","), where each shard holds a ",[1511,44153,44154],{},"different subset"," of the data, typically split by some key like ",[15,44157,35878],{}," or region. A query for a specific user only needs to hit the one shard that owns that user's data.",[11,44160,44161,44162,44165],{},"This is fundamentally different from replication, which keeps ",[1511,44163,44164],{},"full, identical copies"," of the same data on multiple servers. Sharding solves a different problem: when a single database's data or write volume grows too large for one machine to handle efficiently, sharding spreads both the storage and the write load across multiple machines, whereas replication mainly helps with read scaling and availability, not write capacity.",[11,44167,44168,44169,44172],{},"The tradeoffs are significant: queries that need to combine data across shards (like \"find all orders across every user\") become much harder and slower, joins across shards generally aren't practical, and choosing a good ",[10490,44170,44171],{},"shard key"," upfront is critical, since an uneven distribution of data across shards (a \"hot shard\") undermines the whole point. Sharding is usually a last resort, reached only after simpler scaling options like better indexing, caching, or read replicas have been exhausted.",[39,44174,44176],{"id":44175},"nosql-and-data-modeling","NoSQL and Data Modeling",[242,44178,44180],{"id":44179},"_42-what-is-the-difference-between-sql-and-nosql-databases-and-when-would-you-choose-one-over-the-other","42. What is the difference between SQL and NoSQL databases, and when would you choose one over the other?",[11,44182,44183,44186,44187,44190],{},[10490,44184,44185],{},"SQL"," databases (like PostgreSQL or MySQL) are relational: data lives in tables with a fixed schema, and relationships between tables are enforced through foreign keys. ",[10490,44188,44189],{},"NoSQL"," databases are a broad category of non-relational stores (document, key-value, column-family, graph) that generally favor flexible schemas and horizontal scalability over strict consistency guarantees.",[4068,44192,44193,44204],{},[4071,44194,44195],{},[4074,44196,44197,44200,44202],{},[4077,44198,44199],{},"Aspect",[4077,44201,44185],{},[4077,44203,44189],{},[4090,44205,44206,44216,44227,44238],{},[4074,44207,44208,44210,44213],{},[4095,44209,36565],{},[4095,44211,44212],{},"Fixed, defined upfront",[4095,44214,44215],{},"Flexible, can vary per record",[4074,44217,44218,44221,44224],{},[4095,44219,44220],{},"Relationships",[4095,44222,44223],{},"Joins across tables",[4095,44225,44226],{},"Usually denormalized, embedded",[4074,44228,44229,44232,44235],{},[4095,44230,44231],{},"Scaling",[4095,44233,44234],{},"Typically vertical (bigger server)",[4095,44236,44237],{},"Typically horizontal (more servers)",[4074,44239,44240,44242,44245],{},[4095,44241,43833],{},[4095,44243,44244],{},"Strong (ACID) by default",[4095,44246,44247],{},"Often eventual, tunable",[11,44249,44250],{},"Choose SQL when your data is naturally relational and you need strong consistency and complex queries (think financial transactions, order systems). Choose NoSQL when you need to scale out horizontally, your data is naturally hierarchical or unstructured, or your access patterns are simple and known in advance (think user sessions, activity feeds, product catalogs). Many real systems use both, picking the right tool per use case rather than treating it as an all-or-nothing decision.",[242,44252,44254],{"id":44253},"_43-what-are-the-main-types-of-nosql-databases-document-key-value-column-family-graph-give-an-example-use-case-for-each","43. What are the main types of NoSQL databases (document, key-value, column-family, graph)? Give an example use case for each.",[11,44256,44257],{},"NoSQL isn't one thing; it's an umbrella term for several different data models that each solve a different problem.",[4068,44259,44260,44275],{},[4071,44261,44262],{},[4074,44263,44264,44267,44270,44272],{},[4077,44265,44266],{},"Type",[4077,44268,44269],{},"How data is stored",[4077,44271,42984],{},[4077,44273,44274],{},"Good for",[4090,44276,44277,44291,44305,44319],{},[4074,44278,44279,44282,44285,44288],{},[4095,44280,44281],{},"Document",[4095,44283,44284],{},"JSON-like documents",[4095,44286,44287],{},"MongoDB",[4095,44289,44290],{},"Content management, product catalogs",[4074,44292,44293,44296,44299,44302],{},[4095,44294,44295],{},"Key-value",[4095,44297,44298],{},"Simple key maps to a value",[4095,44300,44301],{},"Redis, DynamoDB",[4095,44303,44304],{},"Sessions, caching, feature flags",[4074,44306,44307,44310,44313,44316],{},[4095,44308,44309],{},"Column-family",[4095,44311,44312],{},"Rows with dynamic columns, grouped by column family",[4095,44314,44315],{},"Cassandra, HBase",[4095,44317,44318],{},"Time-series data, write-heavy logging",[4074,44320,44321,44324,44327,44330],{},[4095,44322,44323],{},"Graph",[4095,44325,44326],{},"Nodes and edges with properties",[4095,44328,44329],{},"Neo4j",[4095,44331,44332],{},"Social networks, recommendation engines",[11,44334,44335],{},"The common thread is that each model trades the flexibility of SQL's joins for a structure that maps closely to how the application actually reads and writes data, which usually makes those specific access patterns faster at scale.",[242,44337,44339],{"id":44338},"_44-how-is-data-modeling-different-in-a-document-database-compared-to-a-relational-database","44. How is data modeling different in a document database compared to a relational database?",[11,44341,44342,44343,44346],{},"In a relational database, you model data by normalizing it: splitting information into separate tables to avoid duplication, then joining them back together at query time. In a ",[10490,44344,44345],{},"document database",", you typically model around the application's access patterns instead, often denormalizing (embedding) related data directly into a single document so a common read can be satisfied with one lookup instead of several joins.",[11,44348,44349,44350,44352],{},"For example, a blog post and its comments might be two tables in SQL, joined by a ",[15,44351,36737],{}," foreign key. In a document store, you might embed the comments array directly inside the post document if you almost always read them together:",[83,44354,44356],{"className":14186,"code":44355,"language":9672,"meta":88,"style":88},"{\n    \"title\": \"Intro to Backend Systems\",\n    \"comments\": [\n        { \"user\": \"alex\", \"text\": \"Great post!\" },\n        { \"user\": \"sam\", \"text\": \"Very helpful, thanks.\" }\n    ]\n}\n",[15,44357,44358,44362,44374,44381,44407,44429,44433],{"__ignoreMap":88},[92,44359,44360],{"class":94,"line":95},[92,44361,11212],{"class":119},[92,44363,44364,44367,44369,44372],{"class":94,"line":106},[92,44365,44366],{"class":102},"    \"title\"",[92,44368,5263],{"class":119},[92,44370,44371],{"class":171},"\"Intro to Backend Systems\"",[92,44373,4772],{"class":119},[92,44375,44376,44379],{"class":94,"line":113},[92,44377,44378],{"class":102},"    \"comments\"",[92,44380,14233],{"class":119},[92,44382,44383,44386,44389,44391,44394,44396,44399,44401,44404],{"class":94,"line":138},[92,44384,44385],{"class":119},"        { ",[92,44387,44388],{"class":102},"\"user\"",[92,44390,5263],{"class":119},[92,44392,44393],{"class":171},"\"alex\"",[92,44395,195],{"class":119},[92,44397,44398],{"class":102},"\"text\"",[92,44400,5263],{"class":119},[92,44402,44403],{"class":171},"\"Great post!\"",[92,44405,44406],{"class":119}," },\n",[92,44408,44409,44411,44413,44415,44418,44420,44422,44424,44427],{"class":94,"line":143},[92,44410,44385],{"class":119},[92,44412,44388],{"class":102},[92,44414,5263],{"class":119},[92,44416,44417],{"class":171},"\"sam\"",[92,44419,195],{"class":119},[92,44421,44398],{"class":102},[92,44423,5263],{"class":119},[92,44425,44426],{"class":171},"\"Very helpful, thanks.\"",[92,44428,4506],{"class":119},[92,44430,44431],{"class":94,"line":149},[92,44432,43300],{"class":119},[92,44434,44435],{"class":94,"line":155},[92,44436,4711],{"class":119},[11,44438,44439],{},"The rule of thumb is \"model for your queries\" in document databases versus \"model for your data's structure\" in relational ones. The cost is that updating an embedded value in many documents can be more work than updating one row in a normalized table.",[242,44441,44443],{"id":44442},"_45-what-is-eventual-consistency-and-where-does-it-typically-show-up-in-nosql-systems","45. What is eventual consistency, and where does it typically show up in NoSQL systems?",[11,44445,44446,44449,44450,44453],{},[10490,44447,44448],{},"Eventual consistency"," means that after a write, the system doesn't guarantee every subsequent read sees that write immediately, but it guarantees that if no new writes happen, all replicas will ",[1511,44451,44452],{},"eventually"," converge to the same value. It's common in distributed NoSQL systems that replicate data across multiple nodes for availability and speed.",[11,44455,44456],{},"A typical example: you update your profile picture, and a friend loading your profile from a different data center might see the old picture for a few seconds before the change propagates. This is a deliberate tradeoff, not a bug, made to keep the system fast and available even when some nodes are slow or temporarily unreachable. Systems that need every read to reflect the latest write immediately instead choose strong consistency, usually at the cost of availability or latency.",[242,44458,44460],{"id":44459},"_46-what-is-the-cap-theorem-and-why-cant-a-distributed-system-guarantee-all-three-of-consistency-availability-and-partition-tolerance-at-once","46. What is the CAP theorem, and why can't a distributed system guarantee all three of Consistency, Availability, and Partition tolerance at once?",[11,44462,1792,44463,44466],{},[10490,44464,44465],{},"CAP theorem"," states that a distributed data system can only guarantee two out of three properties at the same time:",[11016,44468,44469,44474,44480],{},[11019,44470,44471,44473],{},[10490,44472,43833],{},": every read receives the most recent write (or an error).",[11019,44475,44476,44479],{},[10490,44477,44478],{},"Availability",": every request receives a (non-error) response, even if it's not the latest data.",[11019,44481,44482,44485],{},[10490,44483,44484],{},"Partition tolerance",": the system keeps working even if network communication between nodes breaks down.",[11,44487,44488,44489,44492],{},"The key insight is that network partitions ",[1511,44490,44491],{},"will"," happen in any real distributed system (cables get cut, servers lose connectivity, data centers get isolated), so partition tolerance isn't really optional; you have to design for it. That leaves a genuine choice only between consistency and availability during a partition. If two nodes can't talk to each other and both receive a write for the same record, the system must either reject one write to stay consistent (sacrificing availability) or accept both and risk serving stale or conflicting data (sacrificing consistency).",[11,44494,44495,44496,44499],{},"In practice, most databases are described as CP (like traditional relational databases or ZooKeeper, which favor consistency) or AP (like Cassandra or DynamoDB, which favor availability). It's worth noting CAP only applies ",[1511,44497,44498],{},"during"," an actual partition; outside of that, most systems try to offer both as best they can.",[242,44501,44503],{"id":44502},"_47-what-is-a-compositecompound-key-and-why-does-key-design-matter-so-much-in-nosql-databases","47. What is a composite/compound key, and why does key design matter so much in NoSQL databases?",[11,44505,6686,44506,44509,44510,44512,44513,44516],{},[10490,44507,44508],{},"composite key"," (also called a compound key) is a key made up of more than one attribute, often a partition key plus a sort key, rather than a single simple value. For example, in a table storing orders, the partition key might be ",[15,44511,43549],{}," and the sort key might be ",[15,44514,44515],{},"order_date",", letting you efficiently fetch \"all orders for this customer, sorted by date.\"",[11,44518,44519],{},"Key design matters enormously in NoSQL because, unlike SQL where you can add indexes and write ad-hoc joins later, most NoSQL databases route and distribute data based on the key you choose, and many don't support flexible ad-hoc queries at all. A poorly chosen key can lead to \"hot partitions,\" where one key gets a disproportionate share of traffic while others sit idle, hurting performance and scalability. Because changing the key design later often means rewriting the whole dataset, it's something you generally need to get right up front by thinking hard about access patterns before writing any code.",[242,44521,44523],{"id":44522},"_48-when-would-you-reach-for-redis-as-a-primary-data-store-instead-of-just-using-it-as-a-cache","48. When would you reach for Redis as a primary data store instead of just using it as a cache?",[11,44525,44526,44527,44530,44531,44534],{},"Most people meet Redis as a cache sitting in front of a \"real\" database, but it's a full in-memory data store with persistence options (",[15,44528,44529],{},"RDB"," snapshots, ",[15,44532,44533],{},"AOF"," logs), so it can also serve as a primary store for the right workload. It makes sense as a primary store when your data is naturally short-lived or small enough to fit in memory, and when you need very low latency access to structures like counters, leaderboards (sorted sets), rate-limit counters, or real-time session state.",[11,44536,44537,44538,44541],{},"For example, a live leaderboard for a game benefits from Redis's sorted-set operations far more than it would from running ",[15,44539,44540],{},"ORDER BY score"," queries against a relational table on every request. The tradeoff is that Redis's durability guarantees are weaker than a disk-based database's by default, and its cost per gigabyte of storage is much higher since everything lives in RAM, so it's usually reserved for data where speed matters more than being the permanent system of record.",[242,44543,44545],{"id":44544},"_49-what-does-schema-less-really-mean-for-a-database-like-mongodb-does-it-actually-mean-theres-no-schema-at-all","49. What does \"schema-less\" really mean for a database like MongoDB? Does it actually mean there's no schema at all?",[11,44547,44548,44549,44551],{},"\"Schema-less\" is a bit of a misnomer. It means the ",[1511,44550,38708],{}," doesn't enforce a rigid, predefined structure on every document the way a relational table enforces columns and types. You can insert a document with fields another document in the same collection doesn't have, without running a migration first.",[11,44553,44554,44555,44557],{},"It does not mean there's no schema at all; your application still has an implicit schema, since your code expects certain fields to exist with certain types. The difference is ",[1511,44556,34105],{}," that schema is enforced: in SQL it's enforced by the database engine at write time, while in a schema-less database it's enforced (or not) by application code, or optionally by tools like MongoDB's schema validation rules. This flexibility is great for rapid iteration and handling varied data, but it shifts responsibility onto developers to keep documents consistent, and inconsistent documents can cause subtle bugs if the application isn't defensive about missing or differently-typed fields.",[39,44559,44561],{"id":44560},"authentication-and-security","Authentication and Security",[242,44563,44565],{"id":44564},"_50-what-is-the-difference-between-authentication-and-authorization","50. What is the difference between authentication and authorization?",[11,44567,44568,44570,44571,44573],{},[10490,44569,37557],{}," answers \"who are you?\", it's the process of verifying an identity, typically through a username/password, a token, or biometrics. ",[10490,44572,37894],{}," answers \"what are you allowed to do?\", it happens after authentication and determines which resources or actions the now-verified identity can access.",[11,44575,44576,44577,44580],{},"A simple way to remember it: logging into an app is authentication; being blocked from an admin page because your account isn't an admin is authorization. The two are almost always implemented as separate layers, and a common mistake is conflating them, for example checking only \"is this user logged in\" without also checking \"is this user allowed to do ",[1511,44578,44579],{},"this specific"," action.\"",[242,44582,44584],{"id":44583},"_51-what-is-the-difference-between-session-based-authentication-and-token-based-authentication","51. What is the difference between session-based authentication and token-based authentication?",[11,44586,14599,44587,44590,44591,44594,44595,44598],{},[10490,44588,44589],{},"session-based authentication",", the server creates a session after login and stores its state (like the user ID) server-side, usually in memory or a database, keyed by a session ID. That session ID is sent to the client as a cookie, and on every request the server looks up the session ID to find out who the user is. In ",[10490,44592,44593],{},"token-based authentication",", the server issues a self-contained token (commonly a ",[15,44596,44597],{},"JWT",") that holds the user's identity and claims directly inside it, cryptographically signed. The server doesn't need to store anything; it just verifies the token's signature on each request.",[4068,44600,44601,44613],{},[4071,44602,44603],{},[4074,44604,44605,44607,44610],{},[4077,44606,44199],{},[4077,44608,44609],{},"Session-based",[4077,44611,44612],{},"Token-based",[4090,44614,44615,44626,44636,44647],{},[4074,44616,44617,44620,44623],{},[4095,44618,44619],{},"State",[4095,44621,44622],{},"Stored server-side",[4095,44624,44625],{},"Stored in the token itself",[4074,44627,44628,44630,44633],{},[4095,44629,44231],{},[4095,44631,44632],{},"Needs shared session store across servers",[4095,44634,44635],{},"Stateless, easier to scale horizontally",[4074,44637,44638,44641,44644],{},[4095,44639,44640],{},"Revocation",[4095,44642,44643],{},"Easy (delete the session)",[4095,44645,44646],{},"Harder (token valid until it expires)",[4074,44648,44649,44652,44655],{},[4095,44650,44651],{},"Typical transport",[4095,44653,44654],{},"Cookie",[4095,44656,44657,44658,44660],{},"Cookie or ",[15,44659,37894],{}," header",[11,44662,44663],{},"Sessions are simpler to revoke instantly (just delete the session record) but require shared storage in a multi-server setup. Tokens scale more easily since any server can verify them without a shared store, but revoking a single token before it expires is genuinely harder, which is why short expiry times and refresh tokens are common companions to this approach.",[242,44665,44667],{"id":44666},"_52-how-does-a-jwt-work-and-what-are-its-three-parts","52. How does a JWT work, and what are its three parts?",[11,44669,6686,44670,44672,44673,81],{},[10490,44671,44597],{}," (JSON Web Token) is a compact, signed string that carries claims (pieces of data) about a user, used to prove identity without the server needing to look anything up in a database. It has three parts separated by dots: ",[15,44674,44675],{},"header.payload.signature",[83,44677,44680],{"className":44678,"code":44679,"language":36619,"meta":88},[40272],"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0In0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c\n",[15,44681,44679],{"__ignoreMap":88},[11016,44683,44684,44693,44703],{},[11019,44685,44686,44689,44690,33758],{},[10490,44687,44688],{},"Header",": metadata, like which signing algorithm is used (e.g. ",[15,44691,44692],{},"HS256",[11019,44694,44695,44698,44699,44702],{},[10490,44696,44697],{},"Payload",": the actual claims, like user ID, roles, and expiry time (",[15,44700,44701],{},"exp","). This part is only base64-encoded, not encrypted, so it's readable by anyone who has the token.",[11019,44704,44705,44708],{},[10490,44706,44707],{},"Signature",": created by hashing the header and payload together with a secret key (or private key). This is what lets the server verify the token hasn't been tampered with.",[11,44710,44711,44712,81],{},"When a client sends a request with a JWT, the server recomputes the signature using its secret and compares it to the one in the token. If they match, the server trusts the claims inside without needing a database lookup, which is what makes JWTs fast and stateless. Because the payload is readable, sensitive data should never be stored in it unencrypted. For a full walkthrough of signing algorithms, expiry, and revocation, see ",[23,44713,37733],{"href":37732},[242,44715,44717,44718,44720,44721,44724],{"id":44716},"_53-what-are-the-security-tradeoffs-of-storing-a-jwt-in-localstorage-versus-an-httponly-cookie","53. What are the security tradeoffs of storing a JWT in ",[15,44719,39263],{}," versus an ",[15,44722,44723],{},"httpOnly"," cookie?",[11,44726,44727,44728,44730,44731,44733,44734,44737,44738,44740],{},"Storing a JWT in ",[15,44729,39263],{}," means your JavaScript code can read and attach it manually, which is convenient, but it also means ",[1511,44732,28404],{}," JavaScript running on the page can read it, including malicious scripts injected via an ",[10490,44735,44736],{},"XSS"," attack. If an attacker manages to run JS on your page, they can simply read the token out of ",[15,44739,39263],{}," and exfiltrate it.",[11,44742,44743,44744,44746,44747,44750,44751,44753,44754,44756],{},"Storing the JWT in an ",[15,44745,44723],{}," cookie means client-side JavaScript can't read it at all (the browser withholds it from ",[15,44748,44749],{},"document.cookie","), so it's immune to token theft via XSS. The tradeoff is that cookies are automatically attached to every request to the domain, which opens the door to ",[10490,44752,32769],{}," attacks unless you add protections like ",[15,44755,42739],{}," cookie attributes or CSRF tokens.",[4068,44758,44759,44771],{},[4071,44760,44761],{},[4074,44762,44763,44765,44768],{},[4077,44764,40429],{},[4077,44766,44767],{},"Vulnerable to",[4077,44769,44770],{},"Protected from",[4090,44772,44773,44785],{},[4074,44774,44775,44779,44782],{},[4095,44776,44777],{},[15,44778,39263],{},[4095,44780,44781],{},"XSS (token theft)",[4095,44783,44784],{},"CSRF (not sent automatically)",[4074,44786,44787,44792,44795],{},[4095,44788,44789,44791],{},[15,44790,44723],{}," cookie",[4095,44793,44794],{},"CSRF (unless mitigated)",[4095,44796,44797],{},"XSS (JS can't read it)",[11,44799,44800,44801,44803,44804,1357,44807,44809],{},"In short, neither option is a silver bullet on its own; ",[15,44802,44723],{}," cookies plus ",[15,44805,44806],{},"SameSite=Strict",[15,44808,42770],{},") plus CSRF tokens is generally considered the safer combination for browser-based apps.",[242,44811,44813],{"id":44812},"_54-what-is-oauth-20-and-what-problem-does-it-solve","54. What is OAuth 2.0, and what problem does it solve?",[11,44815,44816,44819],{},[10490,44817,44818],{},"OAuth 2.0"," is an authorization framework that lets a user grant a third-party application limited access to their data on another service, without ever sharing their password with that third-party app. The problem it solves: before OAuth, \"log in with your Google account\" style features required handing your Google password directly to the third-party app, which is both insecure and gives that app far more access than necessary.",[11,44821,44822,44823,44826],{},"The most common flow, the ",[1511,44824,44825],{},"authorization code"," flow, works like this:",[11074,44828,44829,44832,44835,44840,44847],{},[11019,44830,44831],{},"The user clicks \"Log in with X\" in the client app, which redirects them to the authorization server (X's login page).",[11019,44833,44834],{},"The user logs in and grants consent for specific permissions (scopes).",[11019,44836,44837,44838,81],{},"The authorization server redirects back to the client app with a short-lived ",[10490,44839,44825],{},[11019,44841,44842,44843,44846],{},"The client app exchanges that code (along with a client secret) for an ",[10490,44844,44845],{},"access token"," by calling the authorization server directly.",[11019,44848,44849],{},"The client app uses the access token to call the resource server (X's API) on the user's behalf.",[11,44851,44852],{},[3108,44853],{"alt":44854,"src":44855},"OAuth 2.0 authorization code flow diagram","/post-images/top-111-backend-interview-questions/oauth2-authorization-code-flow-diagram.png",[11,44857,44858],{},"The access token the client app receives is scoped (e.g. \"read your email address\" but not \"read your files\"), which is the core security benefit: the app only gets exactly the access the user approved, and the password itself never leaves the authorization server.",[242,44860,44862],{"id":44861},"_55-is-oauth-an-authentication-protocol-whats-the-relationship-between-oauth-20-and-openid-connect","55. Is OAuth an authentication protocol? What's the relationship between OAuth 2.0 and OpenID Connect?",[11,44864,44865,44866,44869,44870,44873],{},"Strictly speaking, no: OAuth 2.0 is an ",[1511,44867,44868],{},"authorization"," protocol, designed to grant access to resources, not to verify identity. It's a common mistake to use OAuth alone as a login system, because an access token by itself doesn't reliably tell you ",[1511,44871,44872],{},"who"," the user is or guarantee the token was issued for authentication purposes.",[11,44875,44876,44879,44880,44883],{},[10490,44877,44878],{},"OpenID Connect (OIDC)"," is a thin identity layer built directly on top of OAuth 2.0 that adds authentication. It introduces a standardized ",[10490,44881,44882],{},"ID token"," (itself a JWT) containing verified identity claims like the user's ID, name, and email, alongside the regular OAuth access token. So when an app implements \"Sign in with Google,\" it's typically using OIDC, not raw OAuth: OAuth handles the token exchange plumbing, and OIDC adds the piece that actually proves who the user is.",[242,44885,44887],{"id":44886},"_56-how-should-passwords-be-stored-in-a-database-and-why-is-plain-hashing-like-a-single-unsalted-md5-hash-not-enough","56. How should passwords be stored in a database, and why is plain hashing (like a single unsalted MD5 hash) not enough?",[11,44889,44890,44891,6339,44894,44897,44898,195,44900,1375,44903,44906,44907,44910],{},"Passwords should never be stored in plain text, and they shouldn't just be run through a fast, general-purpose hash function like a single unsalted ",[15,44892,44893],{},"MD5",[15,44895,44896],{},"SHA-256"," either. Instead, they should be hashed with a slow, purpose-built password hashing algorithm like ",[15,44899,38179],{},[15,44901,44902],{},"scrypt",[15,44904,44905],{},"Argon2",", which include a random ",[10490,44908,44909],{},"salt"," automatically and are deliberately computationally expensive.",[11,44912,44913,44914,529,44916,44918,44919,44922,44923,44926],{},"The problem with plain fast hashing is twofold. First, ",[15,44915,44893],{},[15,44917,44896],{}," are designed to be ",[1511,44920,44921],{},"fast",", which is exactly the wrong property for password hashing: an attacker with a stolen database can compute billions of hashes per second on modern GPUs and brute-force short or common passwords quickly. Second, without a salt, two users with the same password produce the identical hash, and attackers can use precomputed ",[10490,44924,44925],{},"rainbow tables"," to reverse common hashes instantly.",[83,44928,44931],{"className":44929,"code":44930,"language":36619,"meta":88},[40272],"# Weak: fast, unsalted\nMD5(\"password123\") -> \"482c811da5d5b4bc6d497ffa98491e38\"\n\n# Strong: slow, salted, adaptive cost\nbcrypt(\"password123\", salt=random, cost=12) -> \"$2b$12$KIXQ...unique per user\"\n",[15,44932,44930],{"__ignoreMap":88},[11,44934,44935],{},"A good password hashing algorithm is deliberately slow (tunable via a \"cost\" or \"work factor\" parameter that can be increased as hardware gets faster), which makes brute-forcing at scale impractical even if the database is leaked.",[242,44937,44939],{"id":44938},"_57-what-is-salting-and-why-does-it-defeat-precomputed-rainbow-table-attacks","57. What is salting, and why does it defeat precomputed rainbow table attacks?",[11,44941,6686,44942,44944],{},[10490,44943,44909],{}," is a random value generated uniquely for each password and combined with it before hashing. The salt is stored alongside the hash (it doesn't need to be secret) and used again whenever the password needs to be verified.",[11,44946,44947,44948,44950],{},"Without a salt, two users who happen to pick the same password would produce identical hashes, and an attacker could precompute a giant lookup table (a rainbow table) mapping common passwords to their hashes once, then reuse it against any leaked database instantly. With a unique salt per user, the same password produces a ",[1511,44949,42536],{}," hash for every user, so a precomputed table for one salt is useless against another, forcing the attacker to redo the expensive computation individually for every single password, which makes large-scale rainbow table attacks impractical.",[242,44952,44954],{"id":44953},"_58-what-is-csrf-and-how-do-you-protect-against-it","58. What is CSRF, and how do you protect against it?",[11,44956,44957,44959],{},[10490,44958,32769],{}," (Cross-Site Request Forgery) is an attack where a malicious site tricks a logged-in user's browser into submitting a request to a different site the user is authenticated on, exploiting the fact that browsers automatically attach cookies to requests regardless of which site triggered them. For example, a hidden form on an attacker's page auto-submits a \"transfer money\" request to your bank, and since your browser still has a valid session cookie for the bank, the request looks legitimate.",[11,44961,44962,44963,44966,44967,44969,44970,6339,44972,44974,44975,529,44978,44981,44982,44984],{},"Common defenses include: ",[10490,44964,44965],{},"CSRF tokens"," (a random, unpredictable value embedded in forms that must be sent back and validated server-side, which an attacker's site can't know), setting the ",[15,44968,42739],{}," cookie attribute to ",[15,44971,42767],{},[15,44973,42770],{}," so cookies aren't sent on cross-site requests, and checking the ",[15,44976,44977],{},"Origin",[15,44979,44980],{},"Referer"," headers on state-changing requests. Using ",[15,44983,42739],{}," cookies alone handles most modern cases, but CSRF tokens remain a solid defense-in-depth layer, especially for older browsers.",[242,44986,44988],{"id":44987},"_59-what-is-xss-and-how-do-you-prevent-it-from-the-backends-side","59. What is XSS, and how do you prevent it from the backend's side?",[11,44990,44991,44993],{},[10490,44992,44736],{}," (Cross-Site Scripting) is an attack where an attacker injects malicious JavaScript into a page that other users then load and execute, typically by submitting attacker-controlled content (like a comment or profile bio) that the app later renders without proper escaping. Once that script runs in another user's browser, it can steal cookies, tokens, or perform actions as that user.",[11,44995,44996,44997,195,44999,195,45001,45003,45004,45007,45008,45010],{},"From the backend's side, the main defenses are: always escape or sanitize user-generated content before it's rendered as HTML (encode ",[15,44998,4671],{},[15,45000,1599],{},[15,45002,1807],{},", quotes, etc.), never trust client input even if a frontend framework already escapes by default, and set a strong ",[15,45005,45006],{},"Content-Security-Policy"," header to restrict which scripts are allowed to run on the page at all. Backend-issued cookies containing sensitive tokens should also be marked ",[15,45009,44723],{}," so even a successful script injection can't read them directly. Treating all user input as untrusted data, never as executable code, is the underlying principle behind every one of these defenses.",[242,45012,45014],{"id":45013},"_60-what-is-sql-injection-and-how-do-parameterized-queries-prevent-it","60. What is SQL injection, and how do parameterized queries prevent it?",[11,45016,45017,45019],{},[10490,45018,36859],{}," happens when user input is concatenated directly into a SQL query string, letting an attacker craft input that changes the query's actual logic. A classic example is a login query built by string concatenation:",[83,45021,45023],{"className":43724,"code":45022,"language":43726,"meta":88,"style":88},"-- Vulnerable: user input concatenated directly\nSELECT * FROM users WHERE username = '\" + username + \"' AND password = '\" + password + \"'\n\n-- If username is:  admin' --\n-- The query becomes:\nSELECT * FROM users WHERE username = 'admin' --' AND password = ''\n-- Everything after -- is commented out, bypassing the password check entirely\n",[15,45024,45025,45030,45063,45067,45072,45077,45099],{"__ignoreMap":88},[92,45026,45027],{"class":94,"line":95},[92,45028,45029],{"class":134},"-- Vulnerable: user input concatenated directly\n",[92,45031,45032,45034,45036,45039,45042,45044,45047,45049,45052,45055,45058,45060],{"class":94,"line":106},[92,45033,43733],{"class":98},[92,45035,7352],{"class":98},[92,45037,45038],{"class":98}," FROM",[92,45040,45041],{"class":119}," users ",[92,45043,43595],{"class":98},[92,45045,45046],{"class":119}," username ",[92,45048,126],{"class":98},[92,45050,45051],{"class":171}," '\" + username + \"'",[92,45053,45054],{"class":98}," AND",[92,45056,45057],{"class":98}," password",[92,45059,853],{"class":98},[92,45061,45062],{"class":171}," '\" + password + \"'\n",[92,45064,45065],{"class":94,"line":113},[92,45066,110],{"emptyLinePlaceholder":109},[92,45068,45069],{"class":94,"line":138},[92,45070,45071],{"class":134},"-- If username is:  admin' --\n",[92,45073,45074],{"class":94,"line":143},[92,45075,45076],{"class":134},"-- The query becomes:\n",[92,45078,45079,45081,45083,45085,45087,45089,45091,45093,45096],{"class":94,"line":149},[92,45080,43733],{"class":98},[92,45082,7352],{"class":98},[92,45084,45038],{"class":98},[92,45086,45041],{"class":119},[92,45088,43595],{"class":98},[92,45090,45046],{"class":119},[92,45092,126],{"class":98},[92,45094,45095],{"class":171}," 'admin'",[92,45097,45098],{"class":134}," --' AND password = ''\n",[92,45100,45101],{"class":94,"line":155},[92,45102,45103],{"class":134},"-- Everything after -- is commented out, bypassing the password check entirely\n",[11,45105,45106,45109],{},[10490,45107,45108],{},"Parameterized queries"," (also called prepared statements) fix this by separating the query structure from the data. The query is sent to the database with placeholders, and the actual values are sent separately:",[83,45111,45113],{"className":43724,"code":45112,"language":43726,"meta":88,"style":88},"-- Safe: parameterized\nSELECT * FROM users WHERE username = ? AND password = ?\n-- values [username, password] are bound separately, never parsed as SQL\n",[15,45114,45115,45120,45149],{"__ignoreMap":88},[92,45116,45117],{"class":94,"line":95},[92,45118,45119],{"class":134},"-- Safe: parameterized\n",[92,45121,45122,45124,45126,45128,45130,45132,45134,45136,45139,45142,45144,45146],{"class":94,"line":106},[92,45123,43733],{"class":98},[92,45125,7352],{"class":98},[92,45127,45038],{"class":98},[92,45129,45041],{"class":119},[92,45131,43595],{"class":98},[92,45133,45046],{"class":119},[92,45135,126],{"class":98},[92,45137,45138],{"class":119}," ? ",[92,45140,45141],{"class":98},"AND",[92,45143,45057],{"class":98},[92,45145,853],{"class":98},[92,45147,45148],{"class":119}," ?\n",[92,45150,45151],{"class":94,"line":113},[92,45152,45153],{"class":134},"-- values [username, password] are bound separately, never parsed as SQL\n",[11,45155,45156],{},"Because the database engine treats the bound values purely as data, never as part of the query's syntax, no amount of clever input can change what the query actually does. This is why parameterized queries (or a well-built ORM that uses them under the hood) are the standard defense, rather than trying to manually escape special characters yourself, which is error-prone and easy to get wrong.",[242,45158,45160],{"id":45159},"_61-how-does-rate-limiting-help-protect-a-login-endpoint-against-brute-force-attacks","61. How does rate limiting help protect a login endpoint against brute-force attacks?",[11,45162,45163,45165],{},[10490,45164,40085],{}," restricts how many requests a client (identified by IP, account, or both) can make within a given time window. On a login endpoint, without rate limiting, an attacker can script thousands of password guesses per second against a single account or across many accounts using leaked password lists (a \"credential stuffing\" attack).",[11,45167,45168],{},"By capping login attempts, say 5 per minute per IP or per account, brute-forcing becomes impractically slow: guessing even a modest password space at 5 attempts a minute could take years instead of seconds. Rate limiting is often paired with other measures like exponential backoff, temporary account lockouts, or CAPTCHAs after repeated failures, and logging repeated failures helps detect attacks in progress rather than just slowing them down.",[242,45170,45172],{"id":45171},"_62-what-is-the-principle-of-least-privilege-and-how-does-it-apply-to-backend-systems-eg-database-users-service-permissions","62. What is the principle of least privilege, and how does it apply to backend systems (e.g. database users, service permissions)?",[11,45174,1792,45175,45178],{},[10490,45176,45177],{},"principle of least privilege"," means giving every user, service, or process only the minimum access it needs to do its job, nothing more. The reasoning is straightforward: if a component with broad, unnecessary permissions is ever compromised, an attacker inherits all of that access too, so limiting permissions upfront limits the damage a breach can cause.",[11,45180,45181],{},"In backend systems this shows up in a lot of concrete places: a web application's database user should have permission to read and write its own tables but not to drop tables or access other schemas; a microservice that only ever reads from a queue shouldn't have write or delete permissions on it; an API key used for a read-only reporting job shouldn't also be able to trigger production deployments. Applying least privilege consistently means access reviews aren't just a compliance checkbox; they genuinely reduce the blast radius of any single credential leak or bug.",[242,45183,45185],{"id":45184},"_63-what-is-tlsssl-and-what-does-terminating-tls-mean-in-a-backend-architecture","63. What is TLS/SSL, and what does \"terminating TLS\" mean in a backend architecture?",[11,45187,45188,45191,45192,45195],{},[10490,45189,45190],{},"TLS"," (Transport Layer Security, the modern successor to the older ",[15,45193,45194],{},"SSL"," protocol) encrypts data in transit between a client and a server, so anyone intercepting the traffic (on public wifi, at an ISP, etc.) sees only ciphertext, not the actual request or response content. It also verifies the server's identity via certificates, so clients can trust they're talking to the real server and not an impostor.",[11,45197,178,45198,45201],{},[10490,45199,45200],{},"Terminating TLS","\" refers to the point in the architecture where encrypted traffic is decrypted back into plain HTTP. In many setups, TLS is terminated at a load balancer or reverse proxy sitting in front of the application servers; the connection from the client to that proxy is encrypted, but traffic from the proxy to the internal application servers may run as plain HTTP, since it stays within a trusted private network. This centralizes certificate management in one place instead of every backend instance handling its own TLS, though it does mean that internal network segment must genuinely be trusted, since encryption isn't happening on that leg.",[242,45203,45205],{"id":45204},"_64-what-is-a-refresh-token-and-why-is-it-used-alongside-a-short-lived-access-token","64. What is a refresh token, and why is it used alongside a short-lived access token?",[11,45207,6686,45208,45211,45212,45214],{},[10490,45209,45210],{},"refresh token"," is a long-lived credential used to obtain a new access token without forcing the user to log in again. It works alongside a short-lived ",[10490,45213,44845],{}," (often valid for just 15 minutes to an hour) that's used for actual API requests.",[11,45216,45217,45218,45220],{},"The reasoning behind this split is a security-versus-convenience tradeoff. A short expiry on the access token limits the damage if it's ever stolen, since it becomes useless quickly. But if every token were that short-lived with no way to renew it, users would have to log in constantly, which is a poor experience. The refresh token solves this: it's stored more securely (often in an ",[15,45219,44723],{}," cookie, and used less frequently, which makes it lower-risk to keep valid for days or weeks), and it's only sent to a dedicated endpoint to mint new access tokens, never to general API endpoints. If a refresh token is suspected of being compromised, it can be revoked server-side, cutting off future access even though already-issued access tokens will still work until they naturally expire.",[39,45222,38967],{"id":45223},"caching",[242,45225,45227],{"id":45226},"_65-why-is-caching-important-in-backend-systems-and-whats-the-general-tradeoff-of-introducing-a-cache","65. Why is caching important in backend systems, and what's the general tradeoff of introducing a cache?",[11,45229,45230,45232],{},[10490,45231,38967],{}," means storing a copy of frequently-accessed or expensive-to-compute data somewhere faster to read from, so future requests for the same data can skip the slow path (a database query, an external API call, a heavy computation). It matters because it directly reduces latency for users and cuts load on backend systems that would otherwise redo the same expensive work repeatedly.",[11,45234,45235,45236,45239],{},"The core tradeoff is ",[1511,45237,45238],{},"staleness versus freshness",": a cache is a copy, and copies can drift out of sync with the source of truth. Every caching decision is really a decision about how much staleness is acceptable for that specific piece of data. Caching also adds real complexity, since now there are two places data can live, and keeping them consistent (cache invalidation) is famously one of the harder problems to get right in practice.",[242,45241,45243],{"id":45242},"_66-what-is-the-difference-between-client-side-caching-cdn-caching-and-server-sideapplication-caching","66. What is the difference between client-side caching, CDN caching, and server-side/application caching?",[11,45245,45246],{},"These three caching layers sit at different points between the user and your backend, and each solves a different problem.",[4068,45248,45249,45264],{},[4071,45250,45251],{},[4074,45252,45253,45256,45259,45262],{},[4077,45254,45255],{},"Layer",[4077,45257,45258],{},"Where it lives",[4077,45260,45261],{},"What it caches",[4077,45263,42984],{},[4090,45265,45266,45282,45296],{},[4074,45267,45268,45271,45274,45277],{},[4095,45269,45270],{},"Client-side",[4095,45272,45273],{},"User's browser/device",[4095,45275,45276],{},"Static assets, API responses",[4095,45278,45279,45280],{},"Browser cache, ",[15,45281,39263],{},[4074,45283,45284,45287,45290,45293],{},[4095,45285,45286],{},"CDN",[4095,45288,45289],{},"Edge servers near the user",[4095,45291,45292],{},"Static assets, sometimes full pages",[4095,45294,45295],{},"Images, JS/CSS bundles",[4074,45297,45298,45301,45304,45307],{},[4095,45299,45300],{},"Server-side/application",[4095,45302,45303],{},"Backend infrastructure",[4095,45305,45306],{},"Database query results, computed data",[4095,45308,45309],{},"Redis, in-memory cache",[11,45311,45312,45313,45315],{},"Client-side caching avoids network requests entirely by keeping data on the user's device. ",[10490,45314,45286],{}," caching serves static (and sometimes dynamic) content from a server geographically close to the user, cutting network latency and offloading traffic from origin servers. Server-side caching sits inside the backend itself, saving repeated database queries or expensive computations. A well-built system typically layers all three, letting each layer catch what the layer before it missed.",[242,45317,45319],{"id":45318},"_67-what-is-the-cache-aside-lazy-loading-pattern-and-how-does-it-work","67. What is the cache-aside (lazy-loading) pattern, and how does it work?",[11,45321,45322,45325,45326,45329,45330,45333],{},[10490,45323,45324],{},"Cache-aside"," (also called lazy-loading) is the most common caching pattern for reads. The application code is responsible for managing the cache directly: on a read, it checks the cache first; if the data is there (a ",[10490,45327,45328],{},"cache hit","), it returns it immediately; if not (a ",[10490,45331,45332],{},"cache miss","), it queries the database, then writes the result into the cache before returning it to the caller, so the next request for the same data hits the cache instead.",[83,45335,45338],{"className":45336,"code":45337,"language":36619,"meta":88},[40272],"GET /user/42\n  1. Check cache for key \"user:42\"\n  2. If found (hit)  -> return cached value\n  3. If not found (miss) -> query database\n  4.                     -> store result in cache\n  5.                     -> return value\n",[15,45339,45337],{"__ignoreMap":88},[11,45341,45342],{},[3108,45343],{"alt":45344,"src":45345},"Cache-aside pattern diagram","/post-images/top-111-backend-interview-questions/cache-aside-pattern-diagram.png",[11,45347,45348],{},"Cache-aside is popular because it's simple and resilient: if the cache goes down entirely, the app still works by falling back to the database on every request, just slower. The downside is the first request for any given key always pays the full cost of a cache miss.",[242,45350,45352],{"id":45351},"_68-what-is-the-difference-between-cache-aside-write-through-and-write-behind-caching-strategies","68. What is the difference between cache-aside, write-through, and write-behind caching strategies?",[11,45354,45355,45356,45358],{},"These three strategies differ mainly in ",[1511,45357,32973],{}," data gets written into the cache, which affects consistency, latency, and complexity.",[4068,45360,45361,45375],{},[4071,45362,45363],{},[4074,45364,45365,45367,45370,45372],{},[4077,45366,42981],{},[4077,45368,45369],{},"How writes work",[4077,45371,43833],{},[4077,45373,45374],{},"Write latency",[4090,45376,45377,45390,45404],{},[4074,45378,45379,45381,45384,45387],{},[4095,45380,45324],{},[4095,45382,45383],{},"App writes to DB; cache is only populated on the next read (or invalidated)",[4095,45385,45386],{},"Cache can be briefly stale after a write",[4095,45388,45389],{},"Fast (cache untouched on write)",[4074,45391,45392,45395,45398,45401],{},[4095,45393,45394],{},"Write-through",[4095,45396,45397],{},"App writes to cache, cache synchronously writes to DB",[4095,45399,45400],{},"Cache and DB stay consistent",[4095,45402,45403],{},"Slower (write waits on DB)",[4074,45405,45406,45409,45412,45415],{},[4095,45407,45408],{},"Write-behind",[4095,45410,45411],{},"App writes to cache, cache asynchronously flushes to DB later",[4095,45413,45414],{},"Cache is fresh, DB can lag",[4095,45416,45417],{},"Fastest (write returns immediately)",[11,45419,45420,45422,45423,45425,45426,45428],{},[10490,45421,45324],{}," keeps writes simple (write straight to the database, and either invalidate or let the cache repopulate naturally on the next read). ",[10490,45424,45394],{}," keeps the cache always in sync with the database by writing to both together, at the cost of slower writes since every write waits on the database. ",[10490,45427,45408],{}," optimizes for write speed by writing to the cache immediately and flushing to the database in the background, but this risks losing data if the cache crashes before the flush happens. There's no universally \"best\" option; the right choice depends on whether your workload is more read-heavy or write-heavy, and how much risk of data loss or staleness you can tolerate.",[242,45430,45432],{"id":45431},"_69-what-is-cache-invalidation-and-why-is-it-considered-one-of-the-hard-problems-in-computer-science","69. What is cache invalidation, and why is it considered one of the hard problems in computer science?",[11,45434,45435,45438,45439,45442,45443,45445,45446,45448],{},[10490,45436,45437],{},"Cache invalidation"," is the process of removing or updating stale data in a cache once the underlying source of truth has changed, so the cache doesn't keep serving outdated information. It's famously referenced (alongside \"naming things\") as one of the genuinely hard problems in computer science, half-jokingly, but the difficulty is real: knowing ",[1511,45440,45441],{},"exactly"," when data has changed, ",[1511,45444,32928],{}," cache entries are affected, and ",[1511,45447,7649],{}," to update them without introducing race conditions or serving inconsistent data mid-update gets complicated fast, especially across distributed caches or when multiple services can write to the same underlying data.",[11,45450,45451],{},"Common strategies include invalidating a specific key immediately after a write, using short TTLs so staleness self-heals within a bounded time, or versioning cache keys so old entries simply become unreachable. Each approach makes a different tradeoff between complexity and how long stale data might linger, and there's rarely a solution that's both perfectly fresh and perfectly simple at the same time.",[242,45453,45455],{"id":45454},"_70-what-is-a-ttl-time-to-live-on-a-cache-entry-and-how-do-you-decide-on-a-good-value-for-it","70. What is a TTL (time to live) on a cache entry, and how do you decide on a good value for it?",[11,45457,6686,45458,45461],{},[10490,45459,45460],{},"TTL"," (time to live) is the amount of time a cache entry is allowed to live before it automatically expires and gets removed (or is treated as stale on the next access). It's the simplest and most common way to bound how out-of-date cached data can get, without needing explicit invalidation logic for every write.",[11,45463,45464],{},"Choosing a good TTL is about balancing freshness against cache effectiveness: a very short TTL keeps data fresh but causes frequent cache misses (defeating much of the point of caching), while a very long TTL maximizes hit rates but risks serving stale data for longer. In practice, the value should reflect how often the underlying data actually changes and how tolerant the use case is of staleness; a product price might need a short TTL of a few minutes, while a rarely-changing configuration value might safely use a TTL of hours or days.",[242,45466,45468],{"id":45467},"_71-what-is-cache-stampede-thundering-herd-and-how-do-you-prevent-it","71. What is cache stampede (thundering herd), and how do you prevent it?",[11,45470,6686,45471,45474],{},[10490,45472,45473],{},"cache stampede"," (also called the thundering herd problem) happens when a popular cache entry expires and a large number of concurrent requests all experience a cache miss at the same moment, causing all of them to hit the database (or recompute the expensive value) simultaneously. This sudden spike can overwhelm the database, sometimes badly enough to cause a cascading outage, right at the moment the cache was supposed to be protecting it.",[11,45476,45477],{},"Common prevention techniques include: using a lock (or \"single-flight\" pattern) so only one request recomputes the value while others wait for the result rather than all hitting the database independently; adding jitter (randomness) to TTLs so entries don't all expire at exactly the same time; and probabilistic early expiration, where a request occasionally refreshes a \"soon to expire\" value slightly early instead of waiting for the exact expiry moment. All of these approaches aim at the same goal: making sure only one request pays the cost of a cache miss instead of every concurrent request paying it at once.",[242,45479,45481],{"id":45480},"_72-whats-the-difference-between-redis-and-memcached-at-a-conceptual-level","72. What's the difference between Redis and Memcached at a conceptual level?",[11,45483,45484,45485,834,45488,45491],{},"Both ",[10490,45486,45487],{},"Redis",[10490,45489,45490],{},"Memcached"," are popular in-memory key-value stores commonly used for caching, but they differ in scope and capability.",[4068,45493,45494,45504],{},[4071,45495,45496],{},[4074,45497,45498,45500,45502],{},[4077,45499,44199],{},[4077,45501,45487],{},[4077,45503,45490],{},[4090,45505,45506,45517,45532,45543],{},[4074,45507,45508,45511,45514],{},[4095,45509,45510],{},"Data structures",[4095,45512,45513],{},"Strings, lists, sets, sorted sets, hashes",[4095,45515,45516],{},"Strings only",[4074,45518,45519,45522,45529],{},[4095,45520,45521],{},"Persistence",[4095,45523,45524,45525,529,45527,5182],{},"Optional (",[15,45526,44529],{},[15,45528,44533],{},[4095,45530,45531],{},"None, purely in-memory",[4074,45533,45534,45537,45540],{},[4095,45535,45536],{},"Threading",[4095,45538,45539],{},"Historically single-threaded core",[4095,45541,45542],{},"Multi-threaded",[4074,45544,45545,45548,45551],{},[4095,45546,45547],{},"Extras",[4095,45549,45550],{},"Pub/sub, Lua scripting, replication",[4095,45552,45553],{},"Minimal, focused purely on caching",[11,45555,45556,45557,45559],{},"Memcached is deliberately simple: a fast, multi-threaded, pure key-value cache with no extra features, which makes it very efficient for straightforward caching of simple values. Redis is a richer data structure server that ",[1511,45558,14508],{}," be used purely as a cache, but also supports more complex use cases like leaderboards (sorted sets), pub/sub messaging, and optional persistence so data can survive a restart. The practical rule of thumb: reach for Memcached when you want the simplest possible caching layer for basic key-value pairs, and reach for Redis when you need those richer data structures or features beyond plain caching.",[39,45561,45563],{"id":45562},"concurrency-processes-and-performance","Concurrency, Processes, and Performance",[242,45565,45567],{"id":45566},"_73-what-is-the-difference-between-a-process-and-a-thread","73. What is the difference between a process and a thread?",[11,45569,6686,45570,45573,45574,45577],{},[10490,45571,45572],{},"process"," is an independent running instance of a program, with its own memory space, file handles, and system resources. A ",[10490,45575,45576],{},"thread"," is a unit of execution inside a process; a process can contain multiple threads, and those threads share the same memory space and resources.",[11,45579,45580],{},"Because threads share memory, communicating between them is cheap (just read/write shared variables), but that also means one thread can corrupt data another thread is using if access isn't coordinated. Processes are heavier to create and switch between (the OS has to set up a fresh memory space), but they're isolated from each other, so a crash in one process generally doesn't take down another. This is why a browser tab crashing doesn't usually crash the whole browser: modern browsers run tabs as separate processes.",[242,45582,45584],{"id":45583},"_74-what-is-the-difference-between-concurrency-and-parallelism","74. What is the difference between concurrency and parallelism?",[11,45586,45587,45589,45590,45593],{},[10490,45588,29125],{}," is about structuring a program so multiple tasks can make progress during overlapping time periods, even on a single CPU core, by switching between them. ",[10490,45591,45592],{},"Parallelism"," is about actually running multiple tasks at the exact same instant, which requires multiple CPU cores.",[11,45595,45596,45597,45599],{},"A single-core machine can be concurrent (juggling many tasks by time-slicing) but never truly parallel. A multi-core machine can do both: it can run several tasks in parallel, and each core can also juggle multiple concurrent tasks. A simple way to remember it: concurrency is about dealing with lots of things at once (structure), parallelism is about doing lots of things at once (execution). Go builds this distinction into the language with goroutines and channels; the ",[23,45598,36],{"href":35}," walks through that model in practice.",[242,45601,45603],{"id":45602},"_75-what-is-a-race-condition-and-how-do-you-prevent-one","75. What is a race condition, and how do you prevent one?",[11,45605,6686,45606,45609],{},[10490,45607,45608],{},"race condition"," happens when two or more threads or processes access shared data at the same time, and the final result depends on the unpredictable order in which they run. It's called a \"race\" because the outcome depends on who gets there first.",[83,45611,45614],{"className":45612,"code":45613,"language":36619,"meta":88},[40272],"// two threads run this concurrently on the same `counter` variable\nread counter      // both threads read 5\nadd 1\nwrite counter     // both write 6, one increment is lost\n",[15,45615,45613],{"__ignoreMap":88},[11,45617,45618,45619,45621],{},"In the example above, ",[15,45620,29768],{}," should end up at 7 after two increments, but because both threads read the value before either writes it back, one increment gets silently lost. You prevent race conditions by making the shared access atomic, using a mutex/lock, or using data structures designed to be safely shared (like atomic counters or thread-safe queues) so only one thread can touch the critical section at a time.",[242,45623,45625],{"id":45624},"_76-what-is-a-deadlock-in-general-concurrent-programming-and-what-four-conditions-must-all-hold-for-one-to-occur","76. What is a deadlock in general concurrent programming, and what four conditions must all hold for one to occur?",[11,45627,6686,45628,45630],{},[10490,45629,44047],{}," is a situation where two or more threads or processes are each waiting on a resource the other holds, so none of them can ever proceed. Everyone is stuck waiting forever.",[11,45632,45633],{},"For a deadlock to happen, four conditions (known as the Coffman conditions) all have to be true at once:",[11074,45635,45636,45642,45648,45654],{},[11019,45637,45638,45641],{},[10490,45639,45640],{},"Mutual exclusion",": at least one resource can only be held by one thread at a time.",[11019,45643,45644,45647],{},[10490,45645,45646],{},"Hold and wait",": a thread is holding one resource while waiting for another.",[11019,45649,45650,45653],{},[10490,45651,45652],{},"No preemption",": a resource can't be forcibly taken away from a thread; it has to be released voluntarily.",[11019,45655,45656,45659],{},[10490,45657,45658],{},"Circular wait",": there's a cycle of threads, each waiting on a resource held by the next one in the cycle.",[11,45661,45662],{},"Breaking any single one of these conditions prevents deadlock. In practice, the most common fix is attacking circular wait: always acquire locks in the same, agreed-upon order across the whole codebase, so a cycle can never form.",[242,45664,45666],{"id":45665},"_77-what-is-the-difference-between-blocking-and-non-blocking-io","77. What is the difference between blocking and non-blocking I/O?",[11,45668,32499,45669,45672,45673,45676],{},[10490,45670,45671],{},"blocking I/O",", when code makes a call like reading a file or a network socket, the calling thread stops and waits until the operation finishes before it can do anything else. With ",[10490,45674,45675],{},"non-blocking I/O",", the call returns immediately (often with \"not ready yet\" or a partial result), and the program is free to go do other work and check back later, or get notified when the data is ready.",[11,45678,45679],{},"Blocking I/O is simpler to write and reason about, since code runs top to bottom in order. Non-blocking I/O is more efficient when you have many concurrent operations (like thousands of open network connections), because a single thread doesn't have to sit idle waiting on any one of them; it can juggle all of them.",[242,45681,45683],{"id":45682},"_78-what-is-an-event-loop-and-how-does-it-let-a-single-threaded-server-handle-many-concurrent-requests","78. What is an event loop, and how does it let a single-threaded server handle many concurrent requests?",[11,45685,26615,45686,45689],{},[10490,45687,45688],{},"event loop"," is a runtime mechanism that continuously checks for pending work (like a completed network read, an expired timer, or a callback ready to run) and executes it, one piece at a time, on a single thread. It's the core mechanism behind single-threaded servers that still manage to serve thousands of concurrent connections.",[11,45691,45692],{},"The trick is that the event loop never blocks on slow operations like disk or network I/O. When code asks to read from a socket, the request is handed off to the operating system, and the event loop moves on to process other pending work. Once the OS signals that data is ready, the associated callback gets queued up, and the event loop picks it up on a future iteration.",[83,45694,45697],{"className":45695,"code":45696,"language":36619,"meta":88},[40272],"while true:\n    task = event_queue.wait_for_next_ready_task()\n    run(task)          // runs to completion, no other task runs mid-way\n",[15,45698,45696],{"__ignoreMap":88},[11,45700,45701],{},"This works well because most backend workloads spend the vast majority of their time waiting on I/O (database queries, HTTP calls to other services) rather than doing heavy CPU computation. The limitation is that a single CPU-heavy task (like a large synchronous computation) blocks the entire event loop and delays every other pending request, which is why CPU-bound work is usually offloaded to worker threads or separate processes.",[242,45703,45705],{"id":45704},"_79-what-is-the-difference-between-synchronous-and-asynchronous-code-execution","79. What is the difference between synchronous and asynchronous code execution?",[11,45707,45708,45711,45712,45715],{},[10490,45709,45710],{},"Synchronous"," code runs one statement at a time, in order, and each statement has to finish before the next one starts. ",[10490,45713,45714],{},"Asynchronous"," code lets a slow operation (like a network call) run in the background while the rest of the program keeps executing, and the result is handled later via a callback, promise/future, or similar mechanism.",[11,45717,45718],{},"Synchronous code is easier to follow but wastes time waiting. Asynchronous code is more efficient for I/O-heavy work, but it's harder to reason about, since operations can complete in a different order than they were started, and errors have to be handled at the point the async result comes back rather than with a simple try/catch around sequential code.",[242,45720,45722],{"id":45721},"_80-what-is-a-mutexlock-and-why-is-it-needed-in-concurrent-programming","80. What is a mutex/lock, and why is it needed in concurrent programming?",[11,45724,6686,45725,45728,45729,45732],{},[10490,45726,45727],{},"mutex"," (short for \"mutual exclusion\") is a synchronization primitive that only lets one thread at a time enter a specific section of code, called the ",[1511,45730,45731],{},"critical section",". A thread has to acquire the lock before entering, and release it when it's done; if another thread tries to acquire it while it's held, that thread waits until it's free.",[11,45734,45735],{},"Locks are needed whenever multiple threads read and write shared data, to prevent race conditions. Without a lock around the increment in a shared counter, for example, two threads could read the same value before either writes back, and an update gets lost. The tradeoff is that locks introduce waiting and, if used carelessly (locking in inconsistent order across the code), can cause deadlocks.",[242,45737,45739],{"id":45738},"_81-what-is-thread-starvation","81. What is thread starvation?",[11,45741,45742,45745],{},[10490,45743,45744],{},"Thread starvation"," happens when a thread is repeatedly denied access to a resource it needs, usually because other threads with higher priority or better luck keep getting scheduled ahead of it, so it never gets a fair turn to run. The thread isn't stuck the way it would be in a deadlock; it's technically still able to proceed, it just never actually gets the chance.",[11,45747,45748],{},"It's commonly caused by poor lock fairness (some locks always favor certain threads) or aggressive priority scheduling where low-priority threads keep getting bumped. The usual fix is using fair locks or scheduling policies that guarantee every waiting thread eventually gets a turn.",[242,45750,45752],{"id":45751},"_82-what-is-backpressure-and-why-does-it-matter-when-one-part-of-a-system-is-slower-than-another","82. What is backpressure, and why does it matter when one part of a system is slower than another?",[11,45754,45755,45758],{},[10490,45756,45757],{},"Backpressure"," is a way of signaling \"slow down\" from a slower part of a system back to a faster part that's producing more work than the slower part can consume. Without it, the fast producer just keeps pushing data, and it piles up somewhere (in memory, in a queue) until something runs out of resources and crashes.",[11,45760,45761],{},"Think of a fast API accepting write requests faster than the database behind it can actually persist them. If there's no backpressure, requests queue up in memory indefinitely, memory usage climbs, and eventually the service falls over. With backpressure, the system might reject new requests with a \"too busy\" response, slow down how fast it reads from an upstream queue, or apply a rate limit, so the pressure gets pushed back to the producer instead of building up uncontrollably downstream. It's a core concept in streaming systems, message queues, and reactive programming.",[39,45763,45765],{"id":45764},"distributed-systems-and-scalability","Distributed Systems and Scalability",[242,45767,45769],{"id":45768},"_83-what-is-the-difference-between-vertical-scaling-and-horizontal-scaling","83. What is the difference between vertical scaling and horizontal scaling?",[11,45771,45772,45775,45776,45779],{},[10490,45773,45774],{},"Vertical scaling"," (\"scaling up\") means adding more resources (CPU, RAM) to a single existing machine. ",[10490,45777,45778],{},"Horizontal scaling"," (\"scaling out\") means adding more machines and spreading the load across them.",[4068,45781,45782,45792],{},[4071,45783,45784],{},[4074,45785,45786,45788,45790],{},[4077,45787,44199],{},[4077,45789,45774],{},[4077,45791,45778],{},[4090,45793,45794,45805,45816,45827],{},[4074,45795,45796,45799,45802],{},[4095,45797,45798],{},"How",[4095,45800,45801],{},"Bigger machine",[4095,45803,45804],{},"More machines",[4074,45806,45807,45810,45813],{},[4095,45808,45809],{},"Ceiling",[4095,45811,45812],{},"Limited by the biggest hardware available",[4095,45814,45815],{},"Effectively unlimited",[4074,45817,45818,45821,45824],{},[4095,45819,45820],{},"Complexity",[4095,45822,45823],{},"Simple, no code changes needed",[4095,45825,45826],{},"Needs load balancing, often needs the app to be stateless",[4074,45828,45829,45832,45835],{},[4095,45830,45831],{},"Downtime",[4095,45833,45834],{},"Often requires a restart/resize",[4095,45836,45837],{},"Can add machines without downtime",[11,45839,45840],{},"Vertical scaling is simpler and a good first step, but it eventually hits a hardware ceiling and creates a single point of failure. Horizontal scaling scales further and adds redundancy, but it requires the application to be designed so any instance can handle any request, usually meaning it needs to be stateless or share state externally (in a database or cache).",[242,45842,45844],{"id":45843},"_84-what-is-a-load-balancer-and-what-are-some-common-load-balancing-algorithms","84. What is a load balancer, and what are some common load balancing algorithms?",[11,45846,6686,45847,45850],{},[10490,45848,45849],{},"load balancer"," sits in front of a group of servers and distributes incoming requests across them, so no single server gets overwhelmed and the system can keep working even if one server goes down.",[11,45852,45853],{},"Some common algorithms:",[4068,45855,45856,45866],{},[4071,45857,45858],{},[4074,45859,45860,45863],{},[4077,45861,45862],{},"Algorithm",[4077,45864,45865],{},"How it decides",[4090,45867,45868,45876,45884,45892],{},[4074,45869,45870,45873],{},[4095,45871,45872],{},"Round robin",[4095,45874,45875],{},"Cycles through servers in order, one request each",[4074,45877,45878,45881],{},[4095,45879,45880],{},"Least connections",[4095,45882,45883],{},"Sends the request to the server with the fewest active connections",[4074,45885,45886,45889],{},[4095,45887,45888],{},"Weighted round robin",[4095,45890,45891],{},"Like round robin, but bigger/faster servers get proportionally more requests",[4074,45893,45894,45897],{},[4095,45895,45896],{},"IP hash",[4095,45898,45899],{},"Routes a given client's requests to the same server based on a hash of its IP",[11,45901,45902],{},"Round robin is simple and works well when requests are roughly equal in cost. Least connections is better when request processing times vary a lot, since it adapts to how busy each server actually is. IP hash is used when you need the same client to consistently land on the same server, for example to keep a local, in-memory session working without needing a shared session store.",[11,45904,45905],{},[3108,45906],{"alt":45907,"src":45908},"Load balancer distributing requests across app servers diagram","/post-images/top-111-backend-interview-questions/load-balancer-diagram.png",[242,45910,45912],{"id":45911},"_85-what-is-the-difference-between-a-load-balancer-and-a-reverse-proxy","85. What is the difference between a load balancer and a reverse proxy?",[11,45914,6686,45915,45918,45919,45921],{},[10490,45916,45917],{},"reverse proxy"," is a server that sits in front of one or more backend servers and forwards client requests to them, often also handling things like SSL termination, caching, or compression. A ",[10490,45920,45849],{}," does one specific job: distributing traffic across multiple servers to balance the load.",[11,45923,45924],{},"In practice, the two overlap a lot: a load balancer is essentially a reverse proxy whose primary purpose is traffic distribution, and most reverse proxy software can also do load balancing. The distinction is more about intent than a hard technical line: if the main job is \"which backend gets this request based on capacity\", you're describing load balancing; if the job is broader, like hiding backend topology, caching responses, or terminating TLS, that's the reverse proxy role.",[242,45926,45928],{"id":45927},"_86-what-is-an-api-gateway-and-what-problems-does-it-solve-in-a-microservices-setup","86. What is an API gateway, and what problems does it solve in a microservices setup?",[11,45930,26615,45931,45934],{},[10490,45932,45933],{},"API gateway"," is a single entry point that sits in front of a collection of backend services and routes each incoming request to the right one. Clients talk to the gateway; they don't need to know how many services exist behind it or where each one lives.",[11,45936,45937],{},"In a microservices setup, it solves several problems at once: it centralizes cross-cutting concerns like authentication, rate limiting, request logging, and SSL termination so each individual service doesn't have to reimplement them; it can aggregate responses from multiple services into a single response for the client; and it hides internal service topology, so services can be split, merged, or moved without breaking clients. The tradeoff is that the gateway becomes a critical piece of infrastructure itself, so it needs to be highly available, since every request flows through it.",[242,45939,45941],{"id":45940},"_87-what-is-the-difference-between-a-monolithic-architecture-and-microservices","87. What is the difference between a monolithic architecture and microservices?",[11,45943,6686,45944,45947,45948,45951],{},[10490,45945,45946],{},"monolith"," is an application built and deployed as a single unit, where all the features (user accounts, payments, notifications, etc.) live in one codebase and run as one process. ",[10490,45949,45950],{},"Microservices"," split those same features into separate, independently deployable services that communicate over the network, usually via APIs or messaging.",[4068,45953,45954,45965],{},[4071,45955,45956],{},[4074,45957,45958,45960,45963],{},[4077,45959,44199],{},[4077,45961,45962],{},"Monolith",[4077,45964,45950],{},[4090,45966,45967,45978,45988,45999,46010],{},[4074,45968,45969,45972,45975],{},[4095,45970,45971],{},"Deployment",[4095,45973,45974],{},"One unit, deployed together",[4095,45976,45977],{},"Each service deployed independently",[4074,45979,45980,45982,45985],{},[4095,45981,44231],{},[4095,45983,45984],{},"Scale the whole app together",[4095,45986,45987],{},"Scale each service independently",[4074,45989,45990,45993,45996],{},[4095,45991,45992],{},"Development",[4095,45994,45995],{},"Simple to start, easy to reason about",[4095,45997,45998],{},"More moving parts, needs infra for service communication",[4074,46000,46001,46004,46007],{},[4095,46002,46003],{},"Failure isolation",[4095,46005,46006],{},"A bug can bring down the whole app",[4095,46008,46009],{},"A failing service can be isolated (with the right design)",[4074,46011,46012,46015,46018],{},[4095,46013,46014],{},"Data",[4095,46016,46017],{},"Usually one shared database",[4095,46019,46020],{},"Each service often owns its own data",[11,46022,46023],{},"Neither is universally \"better\". Monoliths are usually faster to build and simpler to operate early on, which is why most systems start as one. Microservices pay off at scale, when different teams need to ship independently and different parts of the system have very different scaling or reliability needs, but they add real operational complexity (network calls where there used to be function calls, distributed debugging, more infrastructure).",[242,46025,46027],{"id":46026},"_88-what-is-service-discovery-and-why-do-microservices-need-it","88. What is service discovery, and why do microservices need it?",[11,46029,46030,46033],{},[10490,46031,46032],{},"Service discovery"," is the mechanism that lets services find each other's network location (IP address and port) at runtime, instead of that information being hardcoded. It matters in microservices because instances are constantly being created, destroyed, moved, or scaled up and down, especially in containerized environments, so a service's address can't be assumed to stay fixed.",[11,46035,46036,46037,46040,46041,46044,46045,46048],{},"There are two common patterns. With a ",[10490,46038,46039],{},"service registry",", each service registers itself on startup and deregisters on shutdown, and other services query the registry to find current addresses. With ",[10490,46042,46043],{},"DNS-based discovery",", a DNS name resolves to the current healthy instances, often managed automatically by the orchestration platform (see ",[23,46046,46047],{"href":14593},"How DNS Works"," for how that resolution actually happens). Without service discovery, you'd have to manually track and update IP addresses every time something scales or restarts, which doesn't work at any real scale.",[242,46050,46052],{"id":46051},"_89-what-is-a-single-point-of-failure-and-how-do-you-go-about-eliminating-one","89. What is a single point of failure, and how do you go about eliminating one?",[11,46054,6686,46055,46058],{},[10490,46056,46057],{},"single point of failure (SPOF)"," is any component in a system that, if it fails, takes down the whole system (or a critical part of it) because nothing else can take over its job. A single database server with no replica, or a single load balancer with no backup, are classic examples.",[11,46060,46061],{},"You eliminate a SPOF by adding redundancy: running multiple instances of the component behind a load balancer, replicating the database so a replica can be promoted if the primary fails, and spreading instances across multiple availability zones or data centers so one physical failure doesn't take everything down. The general principle is that any critical component should have at least one backup that can take over automatically (failover) without a human needing to intervene at 3am.",[242,46063,46065],{"id":46064},"_90-what-is-the-difference-between-horizontal-partitioning-and-vertical-partitioning-of-data","90. What is the difference between horizontal partitioning and vertical partitioning of data?",[11,46067,46068,46071,46072,46075,46076,46079],{},[10490,46069,46070],{},"Horizontal partitioning"," (often called ",[10490,46073,46074],{},"sharding",") splits a table's rows across multiple databases or servers, so each shard holds a subset of the rows, usually based on a key like user ID. ",[10490,46077,46078],{},"Vertical partitioning"," splits a table's columns instead, putting different columns (or groups of columns) into different tables or databases, often to separate frequently-accessed data from rarely-accessed data.",[11,46081,46082,46083,46085],{},"For example, horizontally partitioning a ",[15,46084,35867],{}," table might put users 1 to 1 million on server A and users 1 million to 2 million on server B. Vertically partitioning the same table might put login-related columns (email, password hash) in one table and profile data (bio, avatar, preferences) in another, since they're accessed at different times and rates. Horizontal partitioning is mainly about scaling write/read volume across machines; vertical partitioning is mainly about optimizing access patterns and reducing the amount of unnecessary data read per query.",[242,46087,46089],{"id":46088},"_91-what-is-the-difference-between-eventual-consistency-and-strong-consistency-and-when-is-eventual-consistency-an-acceptable-tradeoff","91. What is the difference between eventual consistency and strong consistency, and when is eventual consistency an acceptable tradeoff?",[11,46091,32499,46092,46095,46096,46099],{},[10490,46093,46094],{},"strong consistency",", once a write completes, every subsequent read (from any node) is guaranteed to see that write immediately. There's never a window where different clients see different, conflicting versions of the data. With ",[10490,46097,46098],{},"eventual consistency",", a write is accepted and will eventually propagate to all nodes, but for some period of time right after the write, different nodes (and therefore different reads) might return stale or different values.",[11,46101,46102],{},"Strong consistency is easier to reason about but usually costs more in latency and availability, since nodes have to coordinate (agree) before confirming a write, and that coordination gets harder to do quickly the more nodes and the more geographically spread out they are. Eventual consistency trades that guarantee for better availability and lower latency, since a node can accept a write and respond immediately without waiting for every other node to agree.",[11,46104,46105],{},"It's an acceptable tradeoff whenever a brief staleness window doesn't cause real harm: a social media \"like\" count that's a few seconds behind, a product view counter, or a user's profile picture propagating across CDN edge nodes are all fine being eventually consistent. It's a poor tradeoff for things like account balances or inventory counts during checkout, where seeing stale data can lead to real, hard-to-reverse mistakes (overselling stock, double-spending).",[242,46107,46109],{"id":46108},"_92-what-is-the-circuit-breaker-pattern-and-why-is-it-used-between-services","92. What is the circuit breaker pattern, and why is it used between services?",[11,46111,1792,46112,46115],{},[10490,46113,46114],{},"circuit breaker"," pattern protects a service from repeatedly calling another service that's already failing or responding too slowly. It works like an electrical circuit breaker: it monitors calls to a downstream service, and if failures cross a threshold, it \"trips\" and stops sending new requests to that service for a while, failing fast instead.",[11,46117,46118,46119,46122,46123,46126,46127,46130],{},"A circuit breaker has three states. In the ",[10490,46120,46121],{},"closed"," state, everything is normal and requests pass through as usual while failures are being counted. Once failures exceed a threshold, it moves to the ",[10490,46124,46125],{},"open"," state, where requests fail immediately (or return a fallback) without even attempting the call, giving the struggling downstream service room to recover. After a cooldown period, it moves to ",[10490,46128,46129],{},"half-open",", where it lets a small number of test requests through; if those succeed, it closes again and resumes normal traffic, and if they fail, it goes back to open.",[11,46132,46133],{},"This matters in distributed systems because without it, a slow or failing downstream service can cause every upstream caller to pile up requests waiting on it (threads blocked, connection pools exhausted), which can cascade into taking down services that were otherwise perfectly healthy. Failing fast with a circuit breaker contains the damage to just the one struggling dependency instead of letting it spread across the whole system.",[242,46135,46137],{"id":46136},"_93-what-does-idempotency-mean-at-the-system-level-and-why-does-it-matter-for-retries-in-distributed-systems","93. What does idempotency mean at the system level, and why does it matter for retries in distributed systems?",[11,46139,46140,46141,46144],{},"An operation is ",[10490,46142,46143],{},"idempotent"," if performing it multiple times has the same effect as performing it once. Calling it once or calling it ten times with the same input leaves the system in the same end state.",[11,46146,46147],{},"This matters enormously for retries. In a distributed system, network calls can fail in ambiguous ways: a request might time out because the response was lost, even though the server actually processed it successfully. When a client retries after a timeout, it genuinely doesn't know whether the original request succeeded or not. If the operation is idempotent, retrying is always safe. If it isn't, a retry can cause real damage, like charging a customer twice.",[11,46149,46150,46151,46153],{},"A common technique is an ",[10490,46152,43113],{},": the client generates a unique ID for an operation (like a payment) and sends it with every retry attempt. The server checks if it has already processed that key before doing the work again.",[83,46155,46157],{"className":14186,"code":46156,"language":9672,"meta":88,"style":88},"{\n  \"idempotency_key\": \"a3f9-92c1-...\",\n  \"amount\": 4999,\n  \"currency\": \"USD\"\n}\n",[15,46158,46159,46163,46175,46187,46197],{"__ignoreMap":88},[92,46160,46161],{"class":94,"line":95},[92,46162,11212],{"class":119},[92,46164,46165,46168,46170,46173],{"class":94,"line":106},[92,46166,46167],{"class":102},"  \"idempotency_key\"",[92,46169,5263],{"class":119},[92,46171,46172],{"class":171},"\"a3f9-92c1-...\"",[92,46174,4772],{"class":119},[92,46176,46177,46180,46182,46185],{"class":94,"line":113},[92,46178,46179],{"class":102},"  \"amount\"",[92,46181,5263],{"class":119},[92,46183,46184],{"class":102},"4999",[92,46186,4772],{"class":119},[92,46188,46189,46192,46194],{"class":94,"line":138},[92,46190,46191],{"class":102},"  \"currency\"",[92,46193,5263],{"class":119},[92,46195,46196],{"class":171},"\"USD\"\n",[92,46198,46199],{"class":94,"line":143},[92,46200,4711],{"class":119},[11,46202,46203],{},"If the server sees the same key twice, it returns the original result instead of charging the customer a second time. Note that not all operations are naturally idempotent: setting a value is idempotent, but incrementing a value is not, unless it's protected with an idempotency key.",[242,46205,46207],{"id":46206},"_94-what-is-the-difference-between-latency-and-throughput","94. What is the difference between latency and throughput?",[11,46209,46210,46213,46214,46217],{},[10490,46211,46212],{},"Latency"," is how long it takes for a single request to complete, usually measured in milliseconds. ",[10490,46215,46216],{},"Throughput"," is how many requests a system can process in a given period of time, usually measured as requests per second.",[11,46219,46220],{},"The two aren't the same thing, and improving one doesn't automatically improve the other. A system can have low latency (each request is fast) but low throughput (it can only handle a few requests at a time), or high throughput (it processes a huge volume overall) while each individual request has noticeably higher latency, for example because requests are being batched together before processing. When people talk about performance, they usually care about both, but which one matters more depends on the use case: a real-time chat feature cares a lot about latency, while a nightly batch report cares more about throughput.",[39,46222,46224],{"id":46223},"messaging-and-asynchronous-communication","Messaging and Asynchronous Communication",[242,46226,46228],{"id":46227},"_95-what-is-a-message-queue-and-what-problem-does-it-solve","95. What is a message queue, and what problem does it solve?",[11,46230,6686,46231,46234],{},[10490,46232,46233],{},"message queue"," is a service that lets one part of a system (the producer) send messages that get stored and later picked up and processed by another part of the system (the consumer), without the two talking to each other directly or needing to be available at the same time.",[11,46236,46237,46238,46241],{},"The core problem it solves is ",[10490,46239,46240],{},"decoupling",". Without a queue, if service A calls service B directly and B is slow or down, A is stuck waiting or failing too. With a queue in between, A can drop a message and move on immediately, and B processes messages whenever it's ready, at its own pace. This also naturally smooths out traffic spikes: if a sudden burst of requests comes in, they pile up in the queue instead of overwhelming the consumer, and the consumer just works through the backlog.",[11,46243,46244],{},[3108,46245],{"alt":46246,"src":46247},"Producer-consumer message queue diagram","/post-images/top-111-backend-interview-questions/message-queue-diagram.png",[242,46249,46251],{"id":46250},"_96-what-is-the-difference-between-a-message-queue-and-a-publishsubscribe-pubsub-system","96. What is the difference between a message queue and a publish/subscribe (pub/sub) system?",[11,46253,46254,46255,46257,46258,46261,46262,46265],{},"In a classic ",[10490,46256,46233],{},", each message is typically delivered to and consumed by exactly one consumer; once it's picked up and processed, it's removed from the queue. In a ",[10490,46259,46260],{},"pub/sub"," system, a publisher sends a message to a ",[1511,46263,46264],{},"topic",", and every subscriber to that topic gets its own copy of the message.",[11,46267,46268],{},"The distinction is really about delivery pattern: queues are for distributing work across a pool of consumers (so the work only gets done once), while pub/sub is for broadcasting an event to multiple independent listeners who each need to react to it in their own way. For example, an \"order placed\" event might be published once, and separately consumed by an email service, an inventory service, and an analytics service, each doing something completely different with the same event. Many real-world message brokers actually support both patterns.",[242,46270,46272],{"id":46271},"_97-what-is-the-difference-between-synchronous-request-response-communication-and-event-driven-communication-between-services","97. What is the difference between synchronous request-response communication and event-driven communication between services?",[11,46274,14599,46275,46278,46279,46282],{},[10490,46276,46277],{},"synchronous request-response"," communication, service A calls service B directly and waits for a response before continuing, similar to a normal function call but over the network. In ",[10490,46280,46281],{},"event-driven"," communication, service A publishes an event describing something that happened, and doesn't wait for or even know which services, if any, react to it.",[11,46284,46285],{},"Request-response is simpler to reason about and gives you an immediate answer, which is useful when you actually need the result right away (checking if a payment succeeded before showing a confirmation page). Event-driven communication decouples services in time and topology: the publisher doesn't need the subscriber to be available at that moment, and new subscribers can be added later without changing the publisher at all. The tradeoff is that event-driven flows are harder to trace and debug, since there's no single call stack to follow, and consistency has to be handled carefully since things happen asynchronously rather than in one atomic step.",[242,46287,46289],{"id":46288},"_98-what-do-at-least-once-at-most-once-and-exactly-once-delivery-guarantees-mean","98. What do \"at-least-once\", \"at-most-once\", and \"exactly-once\" delivery guarantees mean?",[11,46291,46292],{},"These describe how many times a message might be delivered to a consumer when things go wrong (network failures, crashes, retries).",[4068,46294,46295,46307],{},[4071,46296,46297],{},[4074,46298,46299,46302,46304],{},[4077,46300,46301],{},"Guarantee",[4077,46303,42358],{},[4077,46305,46306],{},"Risk",[4090,46308,46309,46320,46331],{},[4074,46310,46311,46314,46317],{},[4095,46312,46313],{},"At-most-once",[4095,46315,46316],{},"Message is delivered zero or one times, never retried",[4095,46318,46319],{},"Messages can be silently lost",[4074,46321,46322,46325,46328],{},[4095,46323,46324],{},"At-least-once",[4095,46326,46327],{},"Message is retried until acknowledged, so it may be delivered more than once",[4095,46329,46330],{},"Consumers may see duplicates",[4074,46332,46333,46336,46339],{},[4095,46334,46335],{},"Exactly-once",[4095,46337,46338],{},"Message is delivered and processed exactly one time, no loss, no duplicates",[4095,46340,46341],{},"Hardest and most expensive to guarantee",[11,46343,46344],{},"At-most-once is the simplest to implement (just send and forget) but risks data loss, so it's only acceptable for things you don't mind occasionally losing, like non-critical metrics. At-least-once is the most common in practice: the system retries until it gets an acknowledgment, which guarantees nothing is lost, but means consumers must be built to safely handle duplicate messages (usually via idempotency). True exactly-once delivery is notoriously difficult across a network; what systems that claim it actually provide is usually at-least-once delivery combined with idempotent processing, which produces the same practical result.",[242,46346,46348],{"id":46347},"_99-what-is-a-dead-letter-queue-and-why-is-it-useful","99. What is a dead-letter queue, and why is it useful?",[11,46350,6686,46351,46354],{},[10490,46352,46353],{},"dead-letter queue (DLQ)"," is a separate queue where messages get moved if they fail to be processed successfully after a certain number of retry attempts, instead of being retried forever or silently dropped.",[11,46356,46357],{},"It's useful because it prevents one bad message (say, one with malformed data that causes the consumer to crash every time) from blocking or endlessly looping the whole queue, while also making sure that message isn't just lost. Once it's sitting in the DLQ, engineers can inspect it, fix the underlying bug, and reprocess it, or at least get alerted that something needs attention. Without a DLQ, a single poison message can either get stuck retrying forever and stall the whole pipeline, or get silently discarded and quietly lose data.",[242,46359,46361],{"id":46360},"_100-what-is-the-producer-consumer-model-and-why-might-a-system-have-multiple-consumers-reading-from-the-same-queue","100. What is the producer-consumer model, and why might a system have multiple consumers reading from the same queue?",[11,46363,1792,46364,46367],{},[10490,46365,46366],{},"producer-consumer model"," describes a pattern where one or more producers generate work (messages, tasks, data) and put it somewhere (usually a queue), and one or more consumers pull that work off and process it, independently of how fast it's being produced.",[11,46369,46370,46371,46374],{},"A system often runs multiple consumers on the same queue purely for ",[10490,46372,46373],{},"throughput",": if one consumer can process 100 messages a second but messages are arriving at 500 a second, adding more consumers lets the work be processed in parallel, so the backlog doesn't keep growing. It also improves resilience: if one consumer instance crashes, the others keep working through the queue, so processing doesn't stop entirely. Most queue systems make sure each message only goes to one consumer at a time, so adding consumers scales throughput without causing the same message to be processed twice.",[242,46376,46378],{"id":46377},"_101-what-is-event-driven-architecture-and-how-does-it-decouple-services-from-each-other","101. What is event-driven architecture, and how does it decouple services from each other?",[11,46380,46381,46384],{},[10490,46382,46383],{},"Event-driven architecture"," is a design style where services communicate primarily by producing and reacting to events (facts about something that happened, like \"order placed\" or \"user signed up\") rather than calling each other directly.",[11,46386,46387],{},"It decouples services in a few concrete ways: the service that produces an event doesn't need to know which services, if any, are listening; new services can start consuming existing events without any change to the producer; and each consumer processes events at its own pace, so a slow or temporarily unavailable consumer doesn't block the producer or other consumers. This makes it easier to add new functionality over time (a new \"send welcome email\" service can just subscribe to the existing \"user signed up\" event) without touching existing code, though it does trade away the simplicity of a straight-line call stack, since a single business action can trigger a chain of reactions spread across many services.",[39,46389,46391],{"id":46390},"testing-deployment-and-observability","Testing, Deployment, and Observability",[242,46393,46395],{"id":46394},"_102-what-is-the-difference-between-unit-testing-integration-testing-and-end-to-end-testing","102. What is the difference between unit testing, integration testing, and end-to-end testing?",[11,46397,46398,46399,46401],{},"These three test types differ mainly in ",[1511,46400,35044],{},", how much of the system they exercise at once.",[4068,46403,46404,46419],{},[4071,46405,46406],{},[4074,46407,46408,46411,46414,46417],{},[4077,46409,46410],{},"Test type",[4077,46412,46413],{},"Scope",[4077,46415,46416],{},"Speed",[4077,46418,42984],{},[4090,46420,46421,46439,46453],{},[4074,46422,46423,46426,46429,46432],{},[4095,46424,46425],{},"Unit",[4095,46427,46428],{},"A single function or class, in isolation",[4095,46430,46431],{},"Very fast",[4095,46433,46434,46435,46438],{},"Testing that a ",[15,46436,46437],{},"calculateDiscount()"," function returns the right value",[4074,46440,46441,46444,46447,46450],{},[4095,46442,46443],{},"Integration",[4095,46445,46446],{},"Multiple components working together",[4095,46448,46449],{},"Medium",[4095,46451,46452],{},"Testing that a service correctly reads and writes to a real (or test) database",[4074,46454,46455,46458,46461,46464],{},[4095,46456,46457],{},"End-to-end (E2E)",[4095,46459,46460],{},"The whole system, as a user would experience it",[4095,46462,46463],{},"Slow",[4095,46465,46466],{},"Simulating a full checkout flow through the actual API/UI",[11,46468,46469],{},"Unit tests are fast and pinpoint exactly what broke, but they don't catch problems that only show up when pieces interact (like a database query that's syntactically fine but wrong). Integration tests catch those interaction bugs but run slower and are more brittle to set up. End-to-end tests give the most confidence that the system actually works for a real user, but they're the slowest, most expensive to maintain, and hardest to debug when they fail. Most teams aim for a pyramid: lots of unit tests, a moderate number of integration tests, and a small number of E2E tests covering critical flows.",[242,46471,46473],{"id":46472},"_103-what-is-mocking-and-why-do-you-mock-dependencies-in-unit-tests","103. What is mocking, and why do you mock dependencies in unit tests?",[11,46475,46476,46479],{},[10490,46477,46478],{},"Mocking"," means replacing a real dependency (a database, an external API, a file system) with a fake, controllable stand-in when writing a test, so the test doesn't actually depend on that real thing being available or behaving a certain way.",[11,46481,46482],{},"You mock dependencies in unit tests to keep them fast, isolated, and predictable. A test that hits a real database is slow, might fail because of network issues or unrelated data changes, and makes it hard to test edge cases (like \"what happens when the database times out\") on demand. With a mock, you can make the fake database return exactly the response, error, or delay you want to test against, every single time, without needing the real thing running at all.",[242,46484,46486],{"id":46485},"_104-what-is-cicd-and-what-problem-does-it-solve-for-a-backend-team","104. What is CI/CD, and what problem does it solve for a backend team?",[11,46488,46489,46492,46493,834,46496,46499],{},[10490,46490,46491],{},"CI/CD"," stands for ",[10490,46494,46495],{},"continuous integration",[10490,46497,46498],{},"continuous delivery/deployment",". Continuous integration means every code change is automatically built and tested as soon as it's pushed, so integration problems are caught within minutes instead of piling up. Continuous delivery/deployment extends that automation to actually releasing the change, either to a staging environment ready for manual approval (delivery) or straight to production automatically (deployment).",[11,46501,46502],{},"The problem it solves is the pain and risk of manual releases. Without CI/CD, merging code from multiple developers and shipping it is a slow, error-prone, manual process: someone has to remember to run the tests, build the artifact, and push it out correctly, and mistakes at any step can ship broken code. CI/CD makes that pipeline automatic and repeatable, catches bugs earlier (right after they're introduced, not weeks later), and makes shipping small, frequent changes low-risk enough that teams can release many times a day instead of once a quarter.",[242,46504,46506],{"id":46505},"_105-what-is-a-container-and-how-is-it-different-from-a-virtual-machine","105. What is a container, and how is it different from a virtual machine?",[11,46508,6686,46509,46512,46513,46516],{},[10490,46510,46511],{},"container"," packages an application together with everything it needs to run (libraries, dependencies, configuration) into a single unit that runs consistently across different environments. A ",[10490,46514,46515],{},"virtual machine (VM)"," emulates an entire computer, including its own full operating system kernel, on top of a host machine.",[4068,46518,46519,46531],{},[4071,46520,46521],{},[4074,46522,46523,46525,46528],{},[4077,46524,44199],{},[4077,46526,46527],{},"Container",[4077,46529,46530],{},"Virtual machine",[4090,46532,46533,46544,46555,46566,46576],{},[4074,46534,46535,46538,46541],{},[4095,46536,46537],{},"OS",[4095,46539,46540],{},"Shares the host machine's kernel",[4095,46542,46543],{},"Runs its own full guest OS",[4074,46545,46546,46549,46552],{},[4095,46547,46548],{},"Size",[4095,46550,46551],{},"Typically megabytes",[4095,46553,46554],{},"Typically gigabytes",[4074,46556,46557,46560,46563],{},[4095,46558,46559],{},"Startup time",[4095,46561,46562],{},"Seconds or less",[4095,46564,46565],{},"Minutes",[4074,46567,46568,46570,46573],{},[4095,46569,43839],{},[4095,46571,46572],{},"Process-level isolation",[4095,46574,46575],{},"Full hardware-level isolation",[4074,46577,46578,46581,46584],{},[4095,46579,46580],{},"Resource overhead",[4095,46582,46583],{},"Low",[4095,46585,46586],{},"Higher",[11,46588,46589],{},"Because containers share the host's kernel instead of running a whole separate OS, they're much lighter weight and start almost instantly, which makes them well suited to running many small services, scaling quickly, and packing more workloads onto the same hardware. VMs offer stronger isolation, since each one is a genuinely separate operating system, which matters more when running fully untrusted or wildly different workloads on the same hardware.",[242,46591,46593],{"id":46592},"_106-why-does-the-twelve-factor-app-principle-recommend-storing-config-in-environment-variables-instead-of-in-code","106. Why does the twelve-factor app principle recommend storing config in environment variables instead of in code?",[11,46595,1792,46596,46599,46600,46603],{},[10490,46597,46598],{},"twelve-factor app"," methodology recommends keeping configuration (database URLs, API keys, feature flags, anything that varies between environments) in ",[10490,46601,46602],{},"environment variables"," rather than hardcoded in the codebase, and the reasoning is mostly about safety and portability.",[11,46605,46606],{},"If config is baked into the code, you either need different code (or a different branch/config file committed) for each environment, which is error-prone and easy to mix up, or you risk accidentally committing secrets like API keys straight into version control where they can leak. Environment variables keep the same build/artifact deployable to development, staging, and production unchanged; only the environment around it differs. It also means secrets never need to touch the codebase or git history at all, which is a meaningful security win.",[242,46608,46610],{"id":46609},"_107-what-is-the-difference-between-logging-metrics-and-tracing","107. What is the difference between logging, metrics, and tracing?",[11,46612,46613,46614,46617],{},"These are the three main pillars of ",[10490,46615,46616],{},"observability",", and each answers a different question about a running system.",[11,46619,46620,46623,46624,46627,46628,46631],{},[10490,46621,46622],{},"Logging"," records discrete, timestamped events, like \"user 42 failed to log in\" or \"payment service returned a 500 error\", usually with enough detail to understand exactly what happened at that moment. ",[10490,46625,46626],{},"Metrics"," are numeric measurements aggregated over time, like requests per second, average response time, or memory usage, useful for spotting trends and setting alerts. ",[10490,46629,46630],{},"Tracing"," follows a single request as it moves through multiple services, recording how long it spent in each one, which is essential for understanding why a particular request was slow in a distributed system where one request might touch a dozen services.",[11,46633,46634,46635,46638,46639,46641,46642,46644],{},"They complement each other: metrics tell you ",[1511,46636,46637],{},"something"," is wrong (error rate spiked), logs help you understand ",[1511,46640,7645],{}," happened in a specific case, and traces show you exactly ",[1511,46643,34105],{}," in a multi-service call chain the time went or the failure occurred.",[242,46646,46648],{"id":46647},"_108-what-is-a-health-check-endpoint-and-why-do-backend-services-expose-one","108. What is a health check endpoint, and why do backend services expose one?",[11,46650,6686,46651,46654,46655,6339,46658,46661],{},[10490,46652,46653],{},"health check endpoint"," is a simple API endpoint (commonly something like ",[15,46656,46657],{},"/health",[15,46659,46660],{},"/status",") that returns whether a service is up and able to handle requests, without doing any real work itself.",[83,46663,46665],{"className":11136,"code":46664,"language":11138,"meta":88,"style":88},"curl -s https://api.example.com/health\n# {\"status\":\"ok\",\"database\":\"connected\"}\n",[15,46666,46667,46676],{"__ignoreMap":88},[92,46668,46669,46671,46673],{"class":94,"line":95},[92,46670,11145],{"class":5161},[92,46672,11148],{"class":102},[92,46674,46675],{"class":171}," https://api.example.com/health\n",[92,46677,46678],{"class":94,"line":106},[92,46679,46680],{"class":134},"# {\"status\":\"ok\",\"database\":\"connected\"}\n",[11,46682,46683],{},"Load balancers and orchestration systems call this endpoint regularly to decide whether an instance should keep receiving traffic. If it stops responding or returns an unhealthy status, the instance can be automatically taken out of rotation, or restarted, without a human needing to notice and intervene manually. Some health checks are \"shallow\" (just confirm the process is running) and others are \"deep\" (also check that the database and other dependencies it needs are reachable), and the right choice depends on what you actually want to happen when a dependency is down.",[242,46685,46687],{"id":46686},"_109-what-is-the-difference-between-a-rolling-deployment-and-a-blue-green-deployment","109. What is the difference between a rolling deployment and a blue-green deployment?",[11,46689,6686,46690,46693,46694,46697],{},[10490,46691,46692],{},"rolling deployment"," updates instances of a service gradually, a few at a time, replacing old versions with new ones until every instance is running the new version. A ",[10490,46695,46696],{},"blue-green deployment"," runs two complete, identical environments (\"blue\" is the current live one, \"green\" is the new one); traffic is switched over all at once from blue to green after the new version is verified.",[4068,46699,46700,46712],{},[4071,46701,46702],{},[4074,46703,46704,46706,46709],{},[4077,46705,44199],{},[4077,46707,46708],{},"Rolling",[4077,46710,46711],{},"Blue-green",[4090,46713,46714,46725,46736,46747],{},[4074,46715,46716,46719,46722],{},[4095,46717,46718],{},"Infrastructure cost",[4095,46720,46721],{},"Lower, reuses existing instances",[4095,46723,46724],{},"Higher, needs two full environments at once",[4074,46726,46727,46730,46733],{},[4095,46728,46729],{},"Rollback speed",[4095,46731,46732],{},"Slower, has to roll instances back gradually",[4095,46734,46735],{},"Instant, just switch traffic back to blue",[4074,46737,46738,46741,46744],{},[4095,46739,46740],{},"Traffic during deploy",[4095,46742,46743],{},"Mixed old and new versions simultaneously",[4095,46745,46746],{},"Never mixed, switches all at once",[4074,46748,46749,46752,46755],{},[4095,46750,46751],{},"Risk window",[4095,46753,46754],{},"Smaller batches limit blast radius",[4095,46756,46757],{},"All-or-nothing cutover",[11,46759,46760],{},"Rolling deployments are cheaper and reduce the blast radius of a bad change, but for a period of time both old and new versions are serving traffic, which requires the two versions to be compatible with each other. Blue-green avoids that mixed-version problem and allows an instant rollback, at the cost of needing double the infrastructure while both environments exist.",[242,46762,46764],{"id":46763},"_110-what-is-graceful-shutdown-and-why-does-a-backend-service-need-to-handle-it-explicitly","110. What is graceful shutdown, and why does a backend service need to handle it explicitly?",[11,46766,46767,46770],{},[10490,46768,46769],{},"Graceful shutdown"," means a service, when told to stop (usually via a termination signal), finishes handling requests it's currently working on and cleans up properly (closing database connections, finishing in-flight writes) before actually exiting, instead of stopping abruptly mid-request.",[83,46772,46775],{"className":46773,"code":46774,"language":36619,"meta":88},[40272],"on SIGTERM:\n    stop accepting new requests\n    wait for in-flight requests to finish (up to a timeout)\n    close database connections, flush logs\n    exit\n",[15,46776,46774],{"__ignoreMap":88},[11,46778,46779],{},"Without this, a service that gets killed mid-request can leave things in a bad state: a client gets a broken connection instead of a response, a database write gets cut off halfway, or a message gets picked off a queue but never actually finishes processing (and might just be lost, depending on the acknowledgment model). This matters constantly in modern deployments, since instances get restarted or replaced all the time during routine deployments and autoscaling, not just during outages, so handling shutdown cleanly needs to be a normal, well-tested code path rather than an afterthought.",[242,46781,46783],{"id":46782},"_111-why-do-backend-services-rely-on-centralized-logging-instead-of-just-writing-logs-to-a-local-file-on-each-server","111. Why do backend services rely on centralized logging instead of just writing logs to a local file on each server?",[11,46785,46786],{},"Writing logs to a local file works fine when there's one server, but it breaks down fast in any real backend system running multiple instances. If each instance writes to its own local disk, debugging an issue means logging into potentially dozens of machines individually and searching each one's files by hand, and if an instance is terminated (common with autoscaling or container restarts), its logs disappear along with it.",[11,46788,46789,46792],{},[10490,46790,46791],{},"Centralized logging"," ships logs from every instance to one shared, searchable system as they're generated, so all logs live in one place regardless of which instance produced them or whether that instance still exists. This makes it possible to search across the whole fleet at once, correlate a single request across multiple services (especially combined with tracing), set up alerts on log patterns, and keep a durable history that survives individual instances being replaced. It's essentially a prerequisite for operating any system with more than a handful of servers.",[39,46794,41863],{"id":41862},[11,46796,46797],{},"These 111 questions cover the ground that comes up again and again in backend interviews, from the basics of HTTP methods to the tradeoffs behind sharding, caching strategies, and message delivery guarantees. Don't try to memorize every answer word for word. Build the underlying mental model instead: why a stateless protocol needs cookies and tokens to fake memory, why a cache is always a tradeoff between speed and staleness, why a distributed system can't have perfect consistency and availability at the same time. Once that model is solid, you'll be able to reason through questions you've never seen phrased this exact way before, which is really what interviewers are testing for.",[11,46799,41882],{},[10887,46801,46802],{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}",{"title":88,"searchDepth":106,"depth":106,"links":46804},[46805,46823,46837,46854,46864,46882,46892,46904,46918,46927,46939],{"id":42087,"depth":106,"text":42088,"children":46806},[46807,46808,46809,46810,46811,46812,46813,46814,46815,46816,46817,46819,46821,46822],{"id":42091,"depth":113,"text":42092},{"id":42224,"depth":113,"text":42225},{"id":42278,"depth":113,"text":42279},{"id":42328,"depth":113,"text":42329},{"id":42421,"depth":113,"text":42422},{"id":42452,"depth":113,"text":42453},{"id":42481,"depth":113,"text":42482},{"id":42526,"depth":113,"text":42527},{"id":42583,"depth":113,"text":42584},{"id":42596,"depth":113,"text":42597},{"id":42682,"depth":113,"text":46818},"11. What is content negotiation, and how does the Accept header relate to it?",{"id":42729,"depth":113,"text":46820},"12. What are cookies used for on the backend, and what do attributes like HttpOnly, Secure, and SameSite do?",{"id":42792,"depth":113,"text":42793},{"id":42804,"depth":113,"text":42805},{"id":42820,"depth":106,"text":42821,"children":46824},[46825,46826,46827,46828,46829,46830,46831,46832,46833,46834,46835,46836],{"id":42824,"depth":113,"text":42825},{"id":42886,"depth":113,"text":42887},{"id":42965,"depth":113,"text":42966},{"id":43054,"depth":113,"text":43055},{"id":43086,"depth":113,"text":43087},{"id":43107,"depth":113,"text":43108},{"id":43152,"depth":113,"text":43153},{"id":43198,"depth":113,"text":43199},{"id":43218,"depth":113,"text":43219},{"id":43315,"depth":113,"text":43316},{"id":43332,"depth":113,"text":43333},{"id":43353,"depth":113,"text":43354},{"id":43376,"depth":106,"text":43377,"children":46838},[46839,46840,46841,46842,46843,46844,46845,46846,46847,46848,46849,46850,46851,46852,46853],{"id":43386,"depth":113,"text":43387},{"id":43411,"depth":113,"text":43412},{"id":43503,"depth":113,"text":43504},{"id":43523,"depth":113,"text":43524},{"id":43568,"depth":113,"text":43569},{"id":43607,"depth":113,"text":43608},{"id":43633,"depth":113,"text":43634},{"id":43653,"depth":113,"text":43654},{"id":43808,"depth":113,"text":43809},{"id":43935,"depth":113,"text":43936},{"id":44041,"depth":113,"text":44042},{"id":44054,"depth":113,"text":44055},{"id":44090,"depth":113,"text":44091},{"id":44104,"depth":113,"text":44105},{"id":44140,"depth":113,"text":44141},{"id":44175,"depth":106,"text":44176,"children":46855},[46856,46857,46858,46859,46860,46861,46862,46863],{"id":44179,"depth":113,"text":44180},{"id":44253,"depth":113,"text":44254},{"id":44338,"depth":113,"text":44339},{"id":44442,"depth":113,"text":44443},{"id":44459,"depth":113,"text":44460},{"id":44502,"depth":113,"text":44503},{"id":44522,"depth":113,"text":44523},{"id":44544,"depth":113,"text":44545},{"id":44560,"depth":106,"text":44561,"children":46865},[46866,46867,46868,46869,46871,46872,46873,46874,46875,46876,46877,46878,46879,46880,46881],{"id":44564,"depth":113,"text":44565},{"id":44583,"depth":113,"text":44584},{"id":44666,"depth":113,"text":44667},{"id":44716,"depth":113,"text":46870},"53. What are the security tradeoffs of storing a JWT in localStorage versus an httpOnly cookie?",{"id":44812,"depth":113,"text":44813},{"id":44861,"depth":113,"text":44862},{"id":44886,"depth":113,"text":44887},{"id":44938,"depth":113,"text":44939},{"id":44953,"depth":113,"text":44954},{"id":44987,"depth":113,"text":44988},{"id":45013,"depth":113,"text":45014},{"id":45159,"depth":113,"text":45160},{"id":45171,"depth":113,"text":45172},{"id":45184,"depth":113,"text":45185},{"id":45204,"depth":113,"text":45205},{"id":45223,"depth":106,"text":38967,"children":46883},[46884,46885,46886,46887,46888,46889,46890,46891],{"id":45226,"depth":113,"text":45227},{"id":45242,"depth":113,"text":45243},{"id":45318,"depth":113,"text":45319},{"id":45351,"depth":113,"text":45352},{"id":45431,"depth":113,"text":45432},{"id":45454,"depth":113,"text":45455},{"id":45467,"depth":113,"text":45468},{"id":45480,"depth":113,"text":45481},{"id":45562,"depth":106,"text":45563,"children":46893},[46894,46895,46896,46897,46898,46899,46900,46901,46902,46903],{"id":45566,"depth":113,"text":45567},{"id":45583,"depth":113,"text":45584},{"id":45602,"depth":113,"text":45603},{"id":45624,"depth":113,"text":45625},{"id":45665,"depth":113,"text":45666},{"id":45682,"depth":113,"text":45683},{"id":45704,"depth":113,"text":45705},{"id":45721,"depth":113,"text":45722},{"id":45738,"depth":113,"text":45739},{"id":45751,"depth":113,"text":45752},{"id":45764,"depth":106,"text":45765,"children":46905},[46906,46907,46908,46909,46910,46911,46912,46913,46914,46915,46916,46917],{"id":45768,"depth":113,"text":45769},{"id":45843,"depth":113,"text":45844},{"id":45911,"depth":113,"text":45912},{"id":45927,"depth":113,"text":45928},{"id":45940,"depth":113,"text":45941},{"id":46026,"depth":113,"text":46027},{"id":46051,"depth":113,"text":46052},{"id":46064,"depth":113,"text":46065},{"id":46088,"depth":113,"text":46089},{"id":46108,"depth":113,"text":46109},{"id":46136,"depth":113,"text":46137},{"id":46206,"depth":113,"text":46207},{"id":46223,"depth":106,"text":46224,"children":46919},[46920,46921,46922,46923,46924,46925,46926],{"id":46227,"depth":113,"text":46228},{"id":46250,"depth":113,"text":46251},{"id":46271,"depth":113,"text":46272},{"id":46288,"depth":113,"text":46289},{"id":46347,"depth":113,"text":46348},{"id":46360,"depth":113,"text":46361},{"id":46377,"depth":113,"text":46378},{"id":46390,"depth":106,"text":46391,"children":46928},[46929,46930,46931,46932,46933,46934,46935,46936,46937,46938],{"id":46394,"depth":113,"text":46395},{"id":46472,"depth":113,"text":46473},{"id":46485,"depth":113,"text":46486},{"id":46505,"depth":113,"text":46506},{"id":46592,"depth":113,"text":46593},{"id":46609,"depth":113,"text":46610},{"id":46647,"depth":113,"text":46648},{"id":46686,"depth":113,"text":46687},{"id":46763,"depth":113,"text":46764},{"id":46782,"depth":113,"text":46783},{"id":41862,"depth":106,"text":41863},"2026-08-04","111 real, commonly-asked backend interview questions and answers for developers with 0-3 years of experience, covering HTTP, API design, databases, security, caching, concurrency, distributed systems, and messaging, explained in the simplest terms.","top-111-backend-interview-questions.png",{},"/backend/top-111-backend-interview-questions",{"title":42073,"description":46941},"Backend/6.top-111-backend-interview-questions",[10977,42069,46948,46949,46950,10979],"System Design","APIs","Databases","fkzmORn6m5nY00dFuJutv3fv-I7y80Dll_4NCwMAghs",1789744090715]