[{"data":1,"prerenderedAt":1241},["ShallowReactive",2],{"news-item-\u002Fnews\u002Ftinh-nang-moi-va-cach-nang-cap-version-tu-laravel-8-len-laravel-10":3},{"id":4,"title":5,"body":6,"category":1228,"created by":1229,"date":1230,"description":1231,"extension":1232,"meta":1233,"navigation":1234,"path":1235,"sections":1236,"seo":1237,"stem":1238,"thumbnail":1239,"__hash__":1240},"content_en\u002Fnews\u002Ftinh-nang-moi-va-cach-nang-cap-version-tu-laravel-8-len-laravel-10.md","From Laravel 8 to Laravel 10 - A migration guide and new features introduction",{"type":7,"value":8,"toc":1175},"minimark",[9,14,18,29,34,42,58,67,76,80,83,87,91,94,104,107,111,129,133,142,148,151,155,159,166,170,174,181,185,189,192,196,200,203,207,216,223,227,231,234,238,242,249,253,257,260,263,267,271,274,278,282,285,289,293,300,304,308,323,327,341,345,348,352,360,362,366,371,381,385,392,396,418,424,427,433,435,438,440,446,450,453,457,463,466,473,479,488,494,503,509,527,533,539,542,547,553,558,561,566,572,578,585,591,596,608,613,616,621,624,630,636,639,645,657,663,669,676,682,686,692,695,699,705,711,717,723,734,740,744,747,749,753,756,760,763,788,805,811,832,846,853,859,862,866,875,881,885,894,900,903,909,913,916,922,925,931,935,958,962,975,979,991,995,998,1004,1008,1021,1027,1030,1036,1039,1043,1046,1052,1056,1059,1062,1068,1071,1077,1081,1084,1090,1095,1098,1103,1106,1112,1115,1121,1127],[10,11,13],"h2",{"id":12},"why-should-you-migrate-from-laravel-8","Why should you migrate from Laravel 8?",[15,16,17],"p",{},"Laravel's new version is now released yearly. Changes such as deprecated features and new features keep coming up. Therefore, the more versions ahead from the latest version you are, the more \"painful\" and time-consuming it is to upgrade compared with upgrading regularly. The main reason for this is that you let your codebase grow too large (classes, methods, and functions become more and more dependent on the others), and it is much harder to make any breaking change. Another thing you should be aware of is that since Laravel 10 was released, Laravel 8 is neither in maintenance nor has support. Therefore, the sooner your project gets upgraded, the better things will be.",[15,19,20,21,28],{},"In this blog, we will show you how to upgrade your project from Laravel 8 to Laravel 10. This guide is about manual upgradation. Therefore, if you want an automated solution, you should consider using the ",[22,23,27],"a",{"href":24,"rel":25},"https:\u002F\u002Flaravelshift.com\u002F",[26],"nofollow","Laravel Shift"," (this is not a free service).",[30,31,33],"h1",{"id":32},"laravel-10s-new-features-introduction","Laravel 10's new features introduction:",[10,35,37,38],{"id":36},"_1-laravel-pennant","1. ",[39,40,41],"strong",{},"Laravel Pennant:",[15,43,44,45,48,49,53,54,57],{},"This is a new package that ships with Laravel 10. It provides a ",[39,46,47],{},"feature flag"," function to your application. When you flag a feature, that feature will be considered available or unavailable. Let's say your application has a ",[50,51,52],"em",{},"\"meeting booking\" feature",", and this feature is ",[50,55,56],{},"only available for users whose role is \"boss\"",". You might manage that feature availability like the below:",[59,60],"img",{"className":61,"alt":64,"src":65,"style":66},[62,63],"block","mx-auto","","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30160709\u002Flaravel-pennant-768x435.png","width: 80%;",[15,68,69,70,75],{},"For more information, please check the ",[22,71,74],{"href":72,"rel":73},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fpennant",[26],"Laravel Pennant documentation",".",[10,77,79],{"id":78},"_2-process-interaction","2. Process Interaction:",[15,81,82],{},"Laravel 10.x introduces a beautiful abstraction layer for starting and interacting with external processes via a new Process facade. You can execute commands in your application or fake for convenient testing, etc.:",[59,84],{"className":85,"alt":64,"src":86,"style":66},[62,63],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30161252\u002Fprocess-call-768x375.png",[10,88,90],{"id":89},"_3-test-profiling","3. Test Profiling:",[15,92,93],{},"The Artisan test command has received a new --profile option that allows you to easily identify the fastest or slowest tests in your application:",[95,96,101],"pre",{"className":97,"code":99,"language":100},[98],"language-text","php artisan test --profile\n","text",[102,103,99],"code",{"__ignoreMap":64},[15,105,106],{},"For convenience, the slowest tests will be displayed directly within the CLI output:",[59,108],{"className":109,"alt":64,"src":110,"style":66},[62,63],"https:\u002F\u002Fuser-images.githubusercontent.com\u002F5457236\u002F217328439-d8d983ec-d0fc-4cde-93d9-ae5bccf5df14.png",[15,112,119,120,128],{"className":113},[114,115,116,117,118],"text-center","text-sm","text-black","italic","-mt-2","\n  (src:\n  ",[22,121,127],{"href":122,"target":123,"rel":124},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Freleases#test-profiling","_blank",[125,126],"noopener","noreferrer","\n    https:\u002F\u002Flaravel.com\u002F\n  ","\n  )\n",[10,130,132],{"id":131},"_4-pest-scaffolding","4. Pest Scaffolding:",[15,134,135,136,141],{},"Pest is a PHP testing framework provided by  PHPUnit. And Laravel has now supported testing with Pest. New Laravel projects may now be created with ",[22,137,140],{"href":138,"rel":139},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Freleases#pest-scaffolding",[26],"Pest test scaffolding"," by default. To opt-in to this feature, provide the --pest flag when creating a new application via the Laravel installer:",[95,143,146],{"className":144,"code":145,"language":100},[98],"laravel new example-application --pest\n",[102,147,145],{"__ignoreMap":64},[149,150],"hr",{},[30,152,154],{"id":153},"laravel-9s-new-features-introduction","Laravel 9's new features introduction:",[10,156,158],{"id":157},"_1-simplified-accessors-and-mutators","1. Simplified Accessors and Mutators:",[15,160,161,162,165],{},"\"Accessors and Mutators\" are also called \"getters and setters\". In Laravel, traditionally, you add a prefix to the attribute name like the one below to declare a \"getter or setter\". The ",[50,163,164],{},"getXAttribute() and setXAttribute()"," API for declaring accessors and mutators is not going away; However, there's a new, simplified approach that will be recommended going forward:",[59,167],{"className":168,"alt":64,"src":169,"style":66},[62,63],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30162149\u002Fgetter-setter-declartion.png",[10,171,173],{"id":172},"_2-enum-attribute-casting","2. Enum Attribute Casting:",[15,175,176,177,180],{},"Now that PHP 8 offers ",[50,178,179],{},"enum"," class support. Therefore, Laravel 9 has been updated to include Eloquent attribute casting to and from an enum object. For example, you can now declare and use an enum like the below:",[59,182],{"className":183,"alt":64,"src":184,"style":66},[62,63],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30162343\u002Fenum-768x786.png",[10,186,188],{"id":187},"_3-implicit-route-bindings-with-enums","3. Implicit Route Bindings With Enums:",[15,190,191],{},"This feature allows you to bind a request's parameter with an enum. Let's say you declare an enum, and then you are binding it like below. With this binding, any request that passes a value that is not a valid enum will lead to an HTTP 404 response. This is convenient since you no longer have to check it in controllers:",[59,193],{"className":194,"alt":64,"src":195,"style":66},[62,63],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30162513\u002Froute-enum-768x360.png",[10,197,199],{"id":198},"_4-forced-scoping-of-route-bindings","4. Forced Scoping Of Route Bindings:",[15,201,202],{},"In previous releases of Laravel, you can scope the second Eloquent model in a route definition such that it must be a child of the previous Eloquent model. For example, consider this route definition that retrieves a blog post by slug for a specific user:",[59,204],{"className":205,"alt":64,"src":206,"style":66},[62,63],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30162851\u002Fscope-biding-1-768x195.png",[15,208,209,210,215],{},"When you declare the route as above, Laravel will try to determine the foreign key base on the predefined set of rules called conventions. But first, you must define the ",[22,211,214],{"href":212,"rel":213},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Frouting#implicit-model-binding-scoping",[26],"custom key binding"," for :slug; otherwise, Laravel will not acknowledge that there is a second model binding required.",[15,217,218,219,222],{},"However, in the newer version, you only have to invoke the ",[50,220,221],{},"scopeBindings()",", and it works the same:",[59,224],{"className":225,"alt":64,"src":226,"style":66},[62,63],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163001\u002Fscope-biding-2-1024x443.png",[10,228,230],{"id":229},"_5-controller-route-groups","5. Controller Route Groups:",[15,232,233],{},"You can now group routes by a controller like the one below:",[59,235],{"className":236,"alt":64,"src":237,"style":66},[62,63],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163135\u002Fcontroller-route-gr-768x171.png",[10,239,241],{"id":240},"_6-full-text-indexes-where-clauses","6. Full-Text Indexes \u002F Where Clauses:",[15,243,244,245,248],{},"You could use new methods like ",[50,246,247],{},"whereFullText(), orWhereFullText()"," to perform full-text search query:",[59,250],{"className":251,"alt":64,"src":252,"style":66},[62,63],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163247\u002Ffull-text-search.png",[10,254,256],{"id":255},"_7-laravel-scout-database-engine","7. Laravel Scout Database Engine:",[15,258,259],{},"The main purpose of Laravel Scout is to simplify the full-text search process of your project. It is a driver-based solution so that you can work with many different engines, such as Elasticsearch, Algolia, MeiliSearch, and MySQL. PostgreSQL,... using the Scout API.",[15,261,262],{},"The idea is to make a search() method available to use for your Eloquent model. Also, it automatically performs indexing when the data is written. Keep in mind that the search() method is not supported complex queries like Elasticsearch DSL; therefore, Scout is only suitable for small or medium projects. Have a look at the below snippet:",[59,264],{"className":265,"alt":64,"src":266,"style":66},[62,63],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163504\u002Fscout-768x279.png",[10,268,270],{"id":269},"_8-rendering-inline-blade-templates","8. Rendering Inline Blade Templates:",[15,272,273],{},"Instead of defining your template in a .blade.php file, you can simply render it within a call to Blade::render(). This is very useful when you need to make an AJAX call to retrieve a partial view for your SPA application.",[59,275],{"className":276,"alt":64,"src":277,"style":66},[62,63],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163626\u002Finline-blade-768x279.png",[10,279,281],{"id":280},"_9-slot-name-shortcut","9. Slot Name Shortcut:",[15,283,284],{},"In previous releases of Laravel, slot names were provided using a name attribute on the x-slot tag. However, beginning in Laravel 9.x, you may specify the slot's name using a convenient, shorter syntax:",[59,286],{"className":287,"alt":64,"src":288,"style":66},[62,63],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163803\u002Fslot-name.png",[10,290,292],{"id":291},"_10-improved-validation-of-nested-array-data","10. Improved Validation Of Nested Array Data:",[15,294,295,296,299],{},"Sometimes you may need to access the value for a given nested array element when assigning validation rules to the attribute. You may now accomplish this using the ",[50,297,298],{},"Rule::forEach()"," method.",[59,301],{"className":302,"alt":64,"src":303,"style":66},[62,63],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163940\u002Fvalidation-ar-768x255.png",[10,305,307],{"id":306},"_11-laravel-breeze-api-nextjs","11. Laravel Breeze API & Next.js:",[15,309,310,311,316,317,322],{},"The ",[22,312,315],{"href":313,"rel":314},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Fstarter-kits#breeze-and-next",[26],"Laravel Breeze"," starter kit has received an \"API\" scaffolding mode and complimentary ",[22,318,321],{"href":319,"rel":320},"https:\u002F\u002Fgithub.com\u002Flaravel\u002Fbreeze-next",[26],"Next.js frontend implementation",". This starter kit scaffolding may be used to jump-start your Laravel applications that are serving as a backend, Laravel Sanctum authenticated API for a JavaScript frontend.",[10,324,326],{"id":325},"_12-bundling-with-vite","12. Bundling with Vite:",[15,328,329,330,335,336,75],{},"Besides new features, bundling your project assets in Laravel is now migrated from using ",[22,331,334],{"href":332,"rel":333},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fmix#main-content",[26],"Mix webpack"," to Vite. You can check it at the official docs of Laravel ",[22,337,340],{"href":338,"rel":339},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fvite#main-content",[26],"here",[10,342,344],{"id":343},"_13-improved-ignition-exception-page","13. Improved Ignition Exception Page:",[15,346,347],{},"The exception debug page has been redesigned from the ground up. The new, improved will help you debug easier and more efficiently:",[59,349],{"className":350,"alt":64,"src":351,"style":66},[62,63],"https:\u002F\u002Fuser-images.githubusercontent.com\u002F483853\u002F149235404-f7caba56-ebdf-499e-9883-cac5d5610369.png",[15,353,119,355,128],{"className":354},[114,115,116,117,118],[22,356,359],{"href":357,"target":123,"rel":358},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Freleases#exception-page",[125,126],"\n    https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Freleases#exception-page\n  ",[149,361],{},[30,363,365],{"id":364},"vulnerabilities-in-security-that-are-covered-by-the-newer-version","Vulnerabilities in security that are covered by the newer version:",[367,368,370],"h3",{"id":369},"blocking-of-the-upload-of-phar-content","Blocking of the upload of .phar content:",[15,372,373,374,377,378,75],{},"When you upload executable PHP files, they are blocked by Laravel for security purposes, including ",[102,375,376],{},"'.php', '.php3', '.php4', '.php5', '.php7', '.php8', '.phtml'"," files. And Laravel has now included the missing extension ",[102,379,380],{},"'.phar'",[367,382,384],{"id":383},"sql-injection-in-sql-server","SQL Injection in SQL Server:",[15,386,387,388,391],{},"Laravel has now covered a vulnerability that opens for SQL Injection attacks when passing user input directly to the ",[102,389,390],{},"limit() and offset()"," functions of SQL Server (Other database drivers such as MySQL and Postgres are not affected by this vulnerability).",[367,393,395],{"id":394},"sql-injection-binding-query-parameter-using-an-array","SQL Injection - Binding query parameter using an array:",[15,397,398,399,402,403,406,407,410,411,414,415,299],{},"The below code has a vulnerability that could lead to a SQL Injection attack. Because the binding value of ",[102,400,401],{},"is_admin"," would-be ",[102,404,405],{},"1"," instead ",[102,408,409],{},"0",". This happens due to the false binding when passing an array ",[102,412,413],{},"$value = [1,1]"," to the ",[102,416,417],{},"where()",[95,419,422],{"className":420,"code":421,"language":100},[98],"User::where('id', [1,1])->where('is_admin', 0)->first();\n\u002F\u002F sql: select * from `users` where `id` = 1 and `is_admin` = 1\n",[102,423,421],{"__ignoreMap":64},[15,425,426],{},"But this has now been covered in the update. The query string will now be like this:",[95,428,431],{"className":429,"code":430,"language":100},[98],"\u002F\u002F sql: select * from `users` where `id` = 1 and `is_admin` = 0\n",[102,432,430],{"__ignoreMap":64},[149,434],{},[15,436,437],{},"In the above section, we have talked about Laravel 9 and Laravel 10 new features, and the security vulnerabilities are covered. Next, let us show you how to upgrade your Laravel project from version 8 to 10.",[149,439],{},[30,441,443],{"id":442},"migrate-your-project-from-laravel-8-to-laravel-10",[39,444,445],{},"Migrate your project from Laravel 8 to Laravel 10:",[10,447,449],{"id":448},"upgrade-to-php-810-composer-220","Upgrade to PHP 8.1.0 & Composer 2.2.0:",[15,451,452],{},"Since Laravel 10 requires at least PHP 8.1.0, you must upgrade to PHP 8.1.0. Also, you must upgrade Composer to 2.2.0 or greater. This is a very crucial step. You must complete it before proceeding to the next section.",[10,454,456],{"id":455},"make-changes-to-your-dependencies-in-composerjson","Make changes to your dependencies in composer.json:",[367,458,460],{"id":459},"a-packages-version-upgrade",[39,461,462],{},"a. Packages version upgrade:",[15,464,465],{},"Below are packages that need to update to newer versions. Follow the instruction to update them.",[15,467,468,469,472],{},"In your ",[50,470,471],{},"composer.json",", change the version of these items as the following:",[95,474,477],{"className":475,"code":476,"language":100},[98],"{\n  \"require\": {\n    \"php\": \"^8.1\",\n    \"laravel\u002Fframework\": \"^10.0\",\n    \"laravel\u002Fsanctum\": \"^3.2\",\n    \"doctrine\u002Fdbal\": \"^3.0\",\n    \"laravel\u002Fpassport\": \"^11.0\"\n  },\n  \"require-dev\": {\n    \"nunomaduro\u002Fcollision\": \"^6.1\",\n    \"spatie\u002Flaravel-ignition\": \"^2.0\"\n  }\n}\n",[102,478,476],{"__ignoreMap":64},[15,480,481,482,487],{},"If your project uses the ",[22,483,486],{"href":484,"rel":485},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fbroadcasting#pusher-channels",[26],"Broadcasting"," feature, you must also change this item version:",[95,489,492],{"className":490,"code":491,"language":100},[98],"{\n  \"require\": {\n    \"pusher\u002Fpusher-php-server\": \"^5.0\"\n  }\n}\n",[102,493,491],{"__ignoreMap":64},[15,495,496,497,502],{},"If you use the S3, FTP, or SFTP drivers through ",[22,498,501],{"href":499,"rel":500},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Ffilesystem#main-content",[26],"Storage",", you must also change this item version:",[95,504,507],{"className":505,"code":506,"language":100},[98],"{\n  \"require\": {\n    \"league\u002Fflysystem-aws-s3-v3\": \"^3.0\",\n    \"league\u002Fflysystem-ftp\": \"^3.0\",\n    \"league\u002Fflysystem-sftp-v3\": \"^3.0\"\n  }\n}\n",[102,508,506],{"__ignoreMap":64},[15,510,511,512,515,516,519,520,523,524,526],{},"Furthermore, if you wish to use PHPUnit 10, you should delete the ",[102,513,514],{},"processUncoveredFiles=\"true\""," attribute from the ",[102,517,518],{},"\u003Ccoverage>"," section of your application's ",[50,521,522],{},"phpunit.xml"," configuration file. Then, update the following dependencies in your application's ",[50,525,471],{}," file:",[95,528,531],{"className":529,"code":530,"language":100},[98],"{\n  \"require-dev\": {\n    \"nunomaduro\u002Fcollision\": \"^7.0\",\n    \"phpunit\u002Fphpunit\": \"^10.0\"\n  }\n}\n",[102,532,530],{"__ignoreMap":64},[367,534,536],{"id":535},"b-removed-packages",[39,537,538],{},"b. Removed packages:",[15,540,541],{},"These packages are no longer required or used, so you should remove it.",[15,543,544],{},[39,545,546],{},"Trusted Proxies:",[15,548,468,549,552],{},[50,550,551],{},"app\u002FHttp\u002FMiddleware\u002FTrustProxies.php"," file, update",[15,554,555],{},[102,556,557],{},"use Fideloper\\Proxy\\TrustProxies as Middleware;",[15,559,560],{},"to this",[15,562,563],{},[102,564,565],{},"use Illuminate\\Http\\Middleware\\TrustProxies as Middleware;",[15,567,568,569,571],{},"Next, in ",[50,570,551],{},", you should update the $headers property definition:",[95,573,576],{"className":574,"code":575,"language":100},[98],"\u002F\u002F Before...\nprotected $headers = Request::HEADER_X_FORWARDED_ALL;\n\u002F\u002F After...\nprotected $headers =\n    Request::HEADER_X_FORWARDED_FOR |\n    Request::HEADER_X_FORWARDED_HOST |\n    Request::HEADER_X_FORWARDED_PORT |\n    Request::HEADER_X_FORWARDED_PROTO |\n    Request::HEADER_X_FORWARDED_AWS_ELB;\n",[102,577,575],{"__ignoreMap":64},[15,579,580,581,584],{},"Finally, you can remove the ",[50,582,583],{},"fideloper\u002Fproxy"," from your application:",[95,586,589],{"className":587,"code":588,"language":100},[98],"{\n  \"require\": {\n    \u002F\u002F Remove this package\n    \"fideloper\u002Fproxy\": \"^4.4\"\n  }\n}\n",[102,590,588],{"__ignoreMap":64},[15,592,593],{},[39,594,595],{},"Fruitcake\u002Flaravel-cors:",[15,597,598,603,604,607],{},[22,599,602],{"href":600,"rel":601},"https:\u002F\u002Fpackagist.org\u002Fpackages\u002Ffruitcake\u002Flaravel-cors",[26],"This package"," is no longer maintained. And in Laravel 10, it is removed. First, in the ",[50,605,606],{},"app\\Http\\Kernel.php,"," you must change the namespace of HandleCors middleware.",[15,609,610],{},[102,611,612],{},"\\Fruitcake\\Cors\\HandleCors::class",[15,614,615],{},"to",[15,617,618],{},[102,619,620],{},"\\Illuminate\\Http\\Middleware\\HandleCors::class",[15,622,623],{},"Then, remove it from composer.json:",[95,625,628],{"className":626,"code":627,"language":100},[98],"{\n  \"require\": {\n    \u002F\u002F Remove this package\n    \"fruitcake\u002Flaravel-cors\": \"^2.0\"\n  }\n}\n",[102,629,627],{"__ignoreMap":64},[367,631,633],{"id":632},"c-packages-replacement",[39,634,635],{},"c. Packages Replacement:",[15,637,638],{},"Switch these items with their replacement in composer.json.",[95,640,643],{"className":641,"code":642,"language":100},[98],"{\n  \"require-dev\": {\n    \u002F\u002F Replace this\n    \"facade\u002Fignition\": \"^2.5\"\n    \u002F\u002F With this\n    \"spatie\u002Flaravel-ignition\": \"^1.0\"\n  }\n}\n",[102,644,642],{"__ignoreMap":64},[15,646,647,648,653,654,656],{},"For the ",[22,649,652],{"href":650,"rel":651},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fnotifications#sms-notifications",[26],"Laravel SMS Notifications"," feature, you must be aware that Nexmo is now acquired by Vonage. Therefore, make changes to your ",[50,655,471],{},":",[95,658,661],{"className":659,"code":660,"language":100},[98],"{\n  \"require\": {\n    \u002F\u002F Replace this\n    \"laravel\u002Fnexmo-notification-channel\": \"^2.0\"\n    \u002F\u002F With this\n    \"laravel\u002Fvonage-notification-channel\": \"^3.0\"\n  }\n}\n",[102,662,660],{"__ignoreMap":64},[367,664,666],{"id":665},"d-swift-mailer-is-replaced-with-symfony-mailer",[39,667,668],{},"d. Swift Mailer is replaced with Symfony Mailer:",[15,670,671,672,675],{},"One of the largest changes in Laravel 9.x is the transition from ",[39,673,674],{},"SwiftMailer",", which is no longer maintained as of December 2021, to Symfony Mailer. To upgrade, run the following command:",[95,677,680],{"className":678,"code":679,"language":100},[98],"composer remove wildbit\u002Fswiftmailer-postmark\ncomposer require symfony\u002Fmailgun-mailer symfony\u002Fpostmark-mailer symfony\u002Fhttp-client\n",[102,681,679],{"__ignoreMap":64},[10,683,685],{"id":684},"run-composer-update","Run \"composer update\":",[15,687,688,689,691],{},"After making all changes to the ",[50,690,471],{},", run the \"composer update\" command. Be aware that all the above packages are just for Laravel basis, so you must also upgrade your project's other dependencies (if required). If you don't upgrade them, they will conflict with Laravel dependencies.",[15,693,694],{},"When you have successfully run the command, next, you need to refactor your source code to remove deprecated features so that your project can normally function. Finally, you might want to consider using new features or applying features that changed in the new version of Laravel.",[10,696,698],{"id":697},"configuration-changes","Configuration changes:",[15,700,468,701,704],{},[50,702,703],{},"config\u002Fdatabase.php",", change the 'schema' to 'search_path' for Postgres database configuration:",[95,706,709],{"className":707,"code":708,"language":100},[98],"'connections' => [\n  'pgsql' => [\n    \u002F\u002F replace this\n    'schema' => 'public',\n    \u002F\u002F by this\n    'search_path' => 'public',\n  ]\n]\n",[102,710,708],{"__ignoreMap":64},[15,712,713,714,656],{},"If you are using SFTP through Laravel Storage, in your ",[50,715,716],{},"config\u002Ffilesystems.php",[95,718,721],{"className":719,"code":720,"language":100},[98],"'sftp' => [\n  \u002F\u002F Replace this         \n  'password' => env('SFTP_PASSPHRASE'),\n  \u002F\u002F By this\n  'passphrase' => env('SFTP_PASSPHRASE'),\n]\n",[102,722,720],{"__ignoreMap":64},[15,724,725,726,729,730,733],{},"Defining ",[102,727,728],{},"stream"," options for the SMTP is no longer supported. Instead, you must define the relevant options directly within the configuration if they are supported. For example, to disable TLS peer verification, you can follow the below configuration. Also, notice that ",[102,731,732],{},"auth_mode"," is commented out since this is no longer available in Laravel's new version.",[95,735,738],{"className":736,"code":737,"language":100},[98],"'smtp' => [\n  \u002F\u002F 'auth_mode' => null,\n\n  \u002F\u002F Laravel 8.x...\n  'stream' => [\n      'ssl' => [\n          'verify_peer' => false,\n      ],\n  ],\n  \u002F\u002F Laravel 9.x...\n  'verify_peer' => false,\n]\n",[102,739,737],{"__ignoreMap":64},[10,741,743],{"id":742},"directories-structure-changes","Directories structure changes:",[15,745,746],{},"In new Laravel applications, the resources\u002Flang directory is now located in the root project directory (lang). If you've been hardcode the lang directory, you must update it. You should use app()->langPath() instead of a hard-coded path.",[149,748],{},[30,750,752],{"id":751},"refactor-your-code","Refactor your code:",[15,754,755],{},"There are breaking changes and deprecated features that are required to make changes in the source code when upgrading to Laravel 10. You don't have to change the code for every feature list below because it depends on whether the feature is used by your project.",[10,757,759],{"id":758},"removed-functions","Removed functions:",[15,761,762],{},"These functions exist in Laravel 8 but are no longer available in Laravel's newer version. So you need to search for all of them in your source code, then fix it manually.",[15,764,765,772,773,776,777,780,781,784,785,75],{},[39,766,767],{},[22,768,771],{"href":769,"rel":770},"https:\u002F\u002Flaravel.com\u002Fapi\u002F8.x\u002FIlluminate\u002FSupport\u002FTraits\u002FEnumeratesValues.html",[26],"EnumeratesValues Trait:"," the ",[50,774,775],{},"reduceWithKeys()"," method is removed, so you might use ",[50,778,779],{},"reduce()"," method instead. And the ",[50,782,783],{},"reduceMany()"," method has been renamed to ",[50,786,787],{},"reduceSpread()",[15,789,790,797,798,801,802,804],{},[39,791,792],{},[22,793,796],{"href":794,"rel":795},"https:\u002F\u002Flaravel.com\u002Fapi\u002F8.x\u002FIlluminate\u002FDatabase\u002FSchema\u002FBuilder.html#method_registerCustomDoctrineType",[26],"Illuminate\\Database\\Schema\\Builder::registerCustomDoctrineType()"," method has been removed. You may use the ",[50,799,800],{},"registerDoctrineType()"," method on the DB facade instead or register custom Doctrine types in the ",[50,803,703],{}," configuration file.",[15,806,807,810],{},[39,808,809],{},"Testing:"," All assertDeleted() method calls should be updated to assertModelMissing().",[15,812,813,772,816,821,822,825,826,831],{},[39,814,815],{},"Queue:",[22,817,820],{"href":818,"rel":819},"https:\u002F\u002Flaravel.com\u002Fapi\u002F9.x\u002FIlluminate\u002FBus\u002FDispatcher.html#method_dispatchNow",[26],"Bus::dispatchNow()"," and ",[50,823,824],{},"dispatch_now()"," methods have been removed. Instead, your application should use the ",[22,827,830],{"href":828,"rel":829},"https:\u002F\u002Flaravel.com\u002Fapi\u002F10.x\u002FIlluminate\u002FBus\u002FDispatcher.html#method_dispatchSync",[26],"Bus::dispatchSync()"," and dispatch_sync() methods, respectively.",[15,833,834,842,843,75],{},[39,835,310,836,841],{},[22,837,840],{"href":838,"rel":839},"https:\u002F\u002Flaravel.com\u002Fapi\u002F9.x\u002FIlluminate\u002FRouting\u002FRedirector.html#method_home",[26],"Redirect::home()"," method"," has been removed. Instead, your application should redirect to an explicitly named route: ",[102,844,845],{},"return Redirect::route('home')",[10,847,849,850],{"id":848},"deprecated-blade-lazy-collections-the-loop-variable","[Deprecated] - Blade - ",[39,851,852],{},"Lazy Collections & The $loop Variable:",[95,854,857],{"className":855,"code":856,"language":100},[98],"@php\n    use App\\Models\\Car;\n    $cars = Car::cursor();  \u002F\u002F cars lazy collection\n    foreach($cars as $c) {\n        echo $loop->iteration;\n    }\n@endphp\n",[102,858,856],{"__ignoreMap":64},[15,860,861],{},"In the above snippet, you are trying to use $loop var in a LazyCollection. This is no longer suporrted. This doesn't mean that the $loop var is removed, but you should not use it with LazyCollection because it causes the entire Collection to be loaded into memory (that is not how LazyCollection is supposed to be).",[10,863,865],{"id":864},"removed-storage","[Removed] - Storage:",[15,867,868,869,874],{},"Storage - Flysystem no longer supports ",[22,870,873],{"href":871,"rel":872},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F8.x\u002Ffilesystem#composer-packages",[26],"cached-adapters"," feature. You should remove it using the composer command:",[95,876,879],{"className":877,"code":878,"language":100},[98],"composer require league\u002Fflysystem-cached-adapter\n",[102,880,878],{"__ignoreMap":64},[10,882,884],{"id":883},"removed-get-db-expression-string-value","[Removed] Get DB Expression string value:",[15,886,887,888,893],{},"In the previous version, you might do this to get the ",[22,889,892],{"href":890,"rel":891},"https:\u002F\u002Flaravel.com\u002Fapi\u002F9.x\u002FIlluminate\u002FDatabase\u002FQuery\u002FExpression.html",[26],"Expression"," string:",[95,895,898],{"className":896,"code":897,"language":100},[98],"$expression = DB::raw('select * from news');\n$expStr = (string)$expression;\n",[102,899,897],{"__ignoreMap":64},[15,901,902],{},"But that is no longer supported, instead:",[95,904,907],{"className":905,"code":906,"language":100},[98],"$expStr = $expression->getValue(DB::connection()->getQueryGrammar());\n",[102,908,906],{"__ignoreMap":64},[10,910,912],{"id":911},"removed-eloquent-models-date-property","[Removed] Eloquent model's $date property:",[15,914,915],{},"The Eloquent model's deprecated $dates property has been removed.",[95,917,920],{"className":918,"code":919,"language":100},[98],"protected $dates = [\n    'deployed_at'\n];\n",[102,921,919],{"__ignoreMap":64},[15,923,924],{},"Your application should now use the $casts property:",[95,926,929],{"className":927,"code":928,"language":100},[98],"protected $casts = [\n    'deployed_at' => 'datetime',\n];\n",[102,930,928],{"__ignoreMap":64},[10,932,934],{"id":933},"removed-testing-service-mocking","[Removed] Testing - Service Mocking:",[15,936,937,938,943,944,947,948,951,952,957],{},"The deprecated ",[22,939,942],{"href":940,"rel":941},"https:\u002F\u002Flaravel.com\u002Fapi\u002F9.x\u002FIlluminate\u002FFoundation\u002FTesting\u002FConcerns\u002FMocksApplicationServices.html",[26],"MocksApplicationServices trait"," has been removed from the framework. This trait provided testing methods such as ",[102,945,946],{},"expectsEvents(), expectsJobs(), and expectsNotifications()",". If your application uses these methods, we recommend transitioning to ",[102,949,950],{},"Event::fake, Bus::fake, and Notification::fake",", respectively. You can learn ",[22,953,956],{"href":954,"rel":955},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Fmocking",[26],"more about mocking"," via fakes in the corresponding documentation for the component you are attempting to fake.",[10,959,961],{"id":960},"changed-validation-the-password-rule","[Changed] Validation - the 'password' Rule:",[15,963,964,969,970,75],{},[22,965,968],{"href":966,"rel":967},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fvalidation#rule-password",[26],"The password rule"," validates that the given input value matches the authenticated user's current password and has been renamed to ",[22,971,974],{"href":972,"rel":973},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fvalidation#rule-current-password",[26],"current_password",[10,976,978],{"id":977},"changed-blade-avoid-overwriting-vue-snippet","[Changed] Blade - Avoid overwriting Vue snippet:",[15,980,981,982,987,988,75],{},"Laravel 9 comes with ",[22,983,986],{"href":984,"rel":985},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fblade#additional-attributes",[26],"new blade directives"," @diabled, @checked, and @selected that will overwrite your Vue directives. Therefore, to escape it, you must replace them with escaped ones ",[102,989,990],{},"@@disabled, @@checked, @@selected",[10,992,994],{"id":993},"changed-collections","[Changed] - Collections:",[15,996,997],{},"You can now pass a closure as the first argument into Collection::when(), unless(). In the previous version, the first argument is always treated as a value and will not be executed. Now you can do this.",[95,999,1002],{"className":1000,"code":1001,"language":100},[98],"$collection->when(function ($collection) {\n  \u002F\u002F This closure is executed...\n  return false;\n}, function ($collection) {\n  \u002F\u002F Not executed since first closure returned \"false\"...\n  $collection->merge([1, 2, 3]);\n});\n",[102,1003,1001],{"__ignoreMap":64},[10,1005,1007],{"id":1006},"changed-eloquent-custom-cast-with-a-null-value","[Changed] - Eloquent - custom cast with a null value:",[15,1009,1010,1011,1016,1017,1020],{},"In Laravel 8, ",[22,1012,1015],{"href":1013,"rel":1014},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Feloquent-mutators#defining-a-mutator",[26],"the mutator set() method"," won't be executed when ",[102,1018,1019],{},"$value = null",". But in Laravel 9, it will be executed. Due to this change, the result of the below snippet is totally different:",[95,1022,1025],{"className":1023,"code":1024,"language":100},[98],"\u002F\u002F In App\\Casts\\FilenameWithTimestamp.php\npublic function set($model, $key, $value, $attributes) {\n  return time() . '_' . $value;\n}\n\n\u002F\u002F In App\\Models\\File.php\nprotected $casts = [\n  'filename' => FilenameWithTimestamp::class\n];\n\n\u002F\u002F Somewhere in your program\n\u002F\u002F With Laravel 8, the result of the echo statement will be: null\n\u002F\u002F With Laravel 9, the result of the echo statement will be: \"20230322_\"\n$file = File::first();\n$file->filename = null;\necho $file->filename;\n\n",[102,1026,1024],{"__ignoreMap":64},[15,1028,1029],{},"As you can see, it makes no sense the filename got prefixed with a timestamp even when it was set to null. So, in Laravel 9, you must handle \"the null case\" for all of your custom casts. E.g.:",[95,1031,1034],{"className":1032,"code":1033,"language":100},[98],"\u002F\u002F In App\\Casts\\FilenameWithTimestamp.php\npublic function set($model, $key, $value, $attributes) {\n  if (empty($value)) {\n    return '';\n  }\n  return time() . '_' . $value;\n}\n",[102,1035,1033],{"__ignoreMap":64},[15,1037,1038],{},"Now it works as expected.",[10,1040,1042],{"id":1041},"changed-storage-throw-exception-behavior","[Changed] Storage - Throw exception behavior:",[15,1044,1045],{},"Previously, Laravel will throw exceptions for failure operations such as reading or deleting unexisting files. But in the newer version, Laravel simply returns the appropriate result, such as false, null, or true,... This change could make an impact on your program if you've been using the try-catch block to handle the failures. Therefore, you either config to the default behavior (like below) or just refactor your code to check for failures (e.g., using if-else block)",[95,1047,1050],{"className":1048,"code":1049,"language":100},[98],"'public' => [\n  'driver' => 'local',\n  \u002F\u002F ...\n  'throw' => true,\n]\n",[102,1051,1049],{"__ignoreMap":64},[10,1053,1055],{"id":1054},"changed-storage-custom-filesystems","[Changed] Storage - Custom Filesystems:",[15,1057,1058],{},"Slight changes have been made to the steps required to register custom filesystem drivers. Therefore, if you were defining your own custom filesystem drivers or using packages that define custom drivers, you should update your code and dependencies.",[15,1060,1061],{},"For example, in Laravel 8.x, a custom filesystem driver might be registered like so:",[95,1063,1066],{"className":1064,"code":1065,"language":100},[98],"use Illuminate\\Support\\Facades\\Storage;\nuse League\\Flysystem\\Filesystem;\nuse Spatie\\Dropbox\\Client as DropboxClient;\nuse Spatie\\FlysystemDropbox\\DropboxAdapter;\n\nStorage::extend('dropbox', function ($app, $config) {\n    $client = new DropboxClient(\n        $config['authorization_token']\n    );\n\n    return new Filesystem(new DropboxAdapter($client));\n});\n",[102,1067,1065],{"__ignoreMap":64},[15,1069,1070],{},"However, in Laravel 9.x, the callback given to the Storage::extend method should return an instance of Illuminate\\Filesystem\\FilesystemAdapter directly:",[95,1072,1075],{"className":1073,"code":1074,"language":100},[98],"use Illuminate\\Filesystem\\FilesystemAdapter;\nuse Illuminate\\Support\\Facades\\Storage;\nuse League\\Flysystem\\Filesystem;\nuse Spatie\\Dropbox\\Client as DropboxClient;\nuse Spatie\\FlysystemDropbox\\DropboxAdapter;\n\nStorage::extend('dropbox', function ($app, $config) {\n    $adapter = new DropboxAdapter(\n        new DropboxClient($config['authorization_token'])\n    );\n\n    return new FilesystemAdapter(\n        new Filesystem($adapter, $config),\n        $adapter,\n        $config\n    );\n});\n",[102,1076,1074],{"__ignoreMap":64},[10,1078,1080],{"id":1079},"changed-migrate-from-swift-mailer-to-symfony-mailer","[Changed] Migrate from Swift Mailer to Symfony Mailer:",[15,1082,1083],{},"In Lavarel 8 and the previous version, Laravel used the Swift Mailer library to send outgoing emails. However, that library is no longer maintained and has been succeeded by Symfony Mailer, which made this transition one of the largest changes. Therefore, you must refactor your code base as below.",[15,1085,1086,1089],{},[39,1087,1088],{},"Renamed \"Swift\" Methods:"," various SwiftMailer-related methods, some of which were undocumented, have been renamed to their Symfony Mailer counterparts. Use the advanced search of your IDE and perform the mass replacement for these methods with the following:",[15,1091,1092],{},[39,1093,1094],{},"MessageSent Event Changes:",[15,1096,1097],{},"Illuminate\\Mail\\Events\\MessageSent event has changed to include an instance of type Symfony\\Component\\Mime\\Email instead of type Swift_Message. This instance contains data about the message before it is sent. At the same time, a new property called sent has been added too. This new property contains data about the message after it is sent, for example, the MessageID.",[15,1099,1100],{},[39,1101,1102],{},"Failed Recipients:",[15,1104,1105],{},"It is no longer possible to retrieve a list of failed recipients after sending a message. Instead, a Symfony\\Component\\Mailer\\Exception\\TransportExceptionInterface exception will be thrown if a message fails to send.",[10,1107,1109],{"id":1108},"comprehensive-exam",[39,1110,1111],{},"Comprehensive Exam:",[15,1113,1114],{},"We have created the exam to check your comprehension of this article. Let’s try it!!",[15,1116,1117],{},[22,1118,1119],{"href":1119,"rel":1120},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002FBhAaDPZtsN",[26],[10,1122,1124],{"id":1123},"references",[39,1125,1126],{},"References:",[1128,1129,1130,1137,1143,1150,1157,1163,1169],"ul",{},[1131,1132,1133],"li",{},[22,1134,1135],{"href":1135,"rel":1136},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Freleases",[26],[1131,1138,1139],{},[22,1140,1141],{"href":1141,"rel":1142},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Freleases",[26],[1131,1144,1145],{},[22,1146,1149],{"href":1147,"rel":1148},"https:\u002F\u002Flaracasts.com\u002Fseries\u002Fwhats-new-in-laravel-9",[26],"Laracasts: What's New in Laravel 9",[1131,1151,1152],{},[22,1153,1156],{"href":1154,"rel":1155},"https:\u002F\u002Flaracasts.com\u002Fseries\u002Fwhats-new-in-laravel-10",[26],"Laracasts: What's New in Laravel 10",[1131,1158,1159],{},[22,1160,1161],{"href":1161,"rel":1162},"https:\u002F\u002Fgithub.com\u002Flaravel\u002Flaravel\u002Fcompare\u002F8.x...9.x",[26],[1131,1164,1165],{},[22,1166,1167],{"href":1167,"rel":1168},"https:\u002F\u002Fgithub.com\u002Flaravel\u002Flaravel\u002Fcompare\u002F9.x...10.x",[26],[1131,1170,1171],{},[22,1172,1173],{"href":1173,"rel":1174},"https:\u002F\u002Fsecurity.snyk.io\u002Fpackage\u002Fcomposer\u002Flaravel%2Fframework",[26],{"title":64,"searchDepth":1176,"depth":1176,"links":1177},2,[1178,1179,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1202,1203,1209,1210,1211,1212,1213,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227],{"id":12,"depth":1176,"text":13},{"id":36,"depth":1176,"text":1180},"1. Laravel Pennant:",{"id":78,"depth":1176,"text":79},{"id":89,"depth":1176,"text":90},{"id":131,"depth":1176,"text":132},{"id":157,"depth":1176,"text":158},{"id":172,"depth":1176,"text":173},{"id":187,"depth":1176,"text":188},{"id":198,"depth":1176,"text":199},{"id":229,"depth":1176,"text":230},{"id":240,"depth":1176,"text":241},{"id":255,"depth":1176,"text":256},{"id":269,"depth":1176,"text":270},{"id":280,"depth":1176,"text":281},{"id":291,"depth":1176,"text":292},{"id":306,"depth":1176,"text":307},{"id":325,"depth":1176,"text":326},{"id":343,"depth":1176,"text":344,"children":1197},[1198,1200,1201],{"id":369,"depth":1199,"text":370},3,{"id":383,"depth":1199,"text":384},{"id":394,"depth":1199,"text":395},{"id":448,"depth":1176,"text":449},{"id":455,"depth":1176,"text":456,"children":1204},[1205,1206,1207,1208],{"id":459,"depth":1199,"text":462},{"id":535,"depth":1199,"text":538},{"id":632,"depth":1199,"text":635},{"id":665,"depth":1199,"text":668},{"id":684,"depth":1176,"text":685},{"id":697,"depth":1176,"text":698},{"id":742,"depth":1176,"text":743},{"id":758,"depth":1176,"text":759},{"id":848,"depth":1176,"text":1214},"[Deprecated] - Blade - Lazy Collections & The $loop Variable:",{"id":864,"depth":1176,"text":865},{"id":883,"depth":1176,"text":884},{"id":911,"depth":1176,"text":912},{"id":933,"depth":1176,"text":934},{"id":960,"depth":1176,"text":961},{"id":977,"depth":1176,"text":978},{"id":993,"depth":1176,"text":994},{"id":1006,"depth":1176,"text":1007},{"id":1041,"depth":1176,"text":1042},{"id":1054,"depth":1176,"text":1055},{"id":1079,"depth":1176,"text":1080},{"id":1108,"depth":1176,"text":1111},{"id":1123,"depth":1176,"text":1126},"tech talk","Briswell Vietnam Co Ltd","2023-05-23","Why should you migrate from Laravel 8? Laravel's new version is now released yearly. Changes such as deprecated features and new features keep coming up. Therefore, the more versions ahead from the latest version you are, the more \"painful\" and time-consuming it is to upgrade compared with upgrading regularly. The main reason for this is that you let your codebase grow too large (classes, methods, and functions become more and more dependent on the others), and it is much harder to make any breaking change. Another thing you should be aware of is that since Laravel 10 was released, Laravel 8 is neither in maintenance nor has support. Therefore, the sooner your project gets upgraded, the better things will be.","md",{},true,"\u002Fnews\u002Ftinh-nang-moi-va-cach-nang-cap-version-tu-laravel-8-len-laravel-10",null,{"title":5,"description":1231},"news\u002Ftinh-nang-moi-va-cach-nang-cap-version-tu-laravel-8-len-laravel-10","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F06151008\u002Flaravel-8-upgrade-thumbnail.jpg","sBAH7vd5kF2dfd2ZTY3x-Wovxug7WzDr8SCsGvWAYlI",1782263095843]