Laravel: Difference between revisions

From David's Wiki
No edit summary
 
(26 intermediate revisions by the same user not shown)
Line 1: Line 1:
Laravel is the most popular PHP framework.<br>
[https://laravel.com Laravel] is a popular MVC framework for PHP.<br>
[https://laravel.com Website]
One of the best parts of Laravel is their excellent video course on web development.
The course is published on Laracasts.


=Usage=
==Usage==
==Installation==
===Installation===
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
composer global require laravel/installer
composer global require laravel/installer
</syntaxhighlight>
</syntaxhighlight>
==Creating a new project==
===Creating a new project===
Run the following commands.<br>
Run the following commands.<br>
Initialize a laravel project then <code>cd</code> into your project folder and install all php and node dependencies.<br>
Initialize a laravel project then <code>cd</code> into your project folder and install all php and node dependencies.<br>
Line 20: Line 21:
</syntaxhighlight>
</syntaxhighlight>


==Copying an existing project==
===Copying an existing project===
After you git pull an existing project, you will need to do the following to get it running.<br>
After you git pull an existing project, you will need to do the following to get it running.<br>
Note: The app key is used for encrypting cookies.<br>
Note: The app key is used for encrypting cookies.<br>
Line 26: Line 27:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
composer install
composer install
npm install
npm ci
cp .env.example .env
cp .env.example .env
# Fill in the .env config variables such as database, mail server, API keys, ...
# Fill in the .env config variables such as database, mail server, API keys, ...
Line 34: Line 35:
</syntaxhighlight>
</syntaxhighlight>


=Resources=
==Blade==
===Components===
:Note: Components were completely revamped in Laravel 7. 
If you don't know anything watch [https://laracasts.com/series/blade-component-cookbook Blade Component Cookbook] or read the [https://laravel.com/docs/7.x/blade Blade Templates]. 
 
Components in Laravel 7 have two parts:
* A php script in <code>app/View/Components</code>. E.g. <code>MyComponent.php</code>
* A blade template in <code>resources/views/components</code>. E.g. <code>my-component.blade.php</code>
 
To get started, run:
<pre>
php artisan make:component Alert
</pre>
 
==Controllers==
[https://laravel.com/docs/6.x/controllers Documentation]<br>
Controllers handle requests. The route file associates entry points with controller methods.<br>
To make a controller, run <code>php artisan make:controller <name of controller></code>.<br>
Add the <code>-r</code> flag to automatically add REST methods.
 
==Routing==
Routing is handled in the <code>routes/web.php</code> file.<br>
[https://laravel.com/docs/6.x/routing Documentation]
 
===RESTful===
Note that for put, patch, delete you will need <code>@method('PATCH')</code> in your form html element.<br>
Or you can use an ajax request via fetch or jQuery.
<syntaxhighlight lang="php">
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
</syntaxhighlight>
 
Theses can also be simplified with a single <code>Route::resource($uri, $className);</code> for a [https://laravel.com/docs/7.x/controllers resource controller]
 
===Parameters/Variables===
<syntaxhighlight lang="php">
Route::get('user/{id}', function ($id) {
    return 'User '.$id;
});
</syntaxhighlight>
 
==Database==
 
===Query Builder===
 
;From subquery:
<syntaxhighlight lang="php">
$subquery = DB::connection('bayarea')->table(DB::raw("restaurants x, parking y"))
  ->select("x.id as id1", "y.id as id2")->where("x.id", "=", $restaurant_id);
$mainquery = DB::connection('bayarea')->table(DB::raw("({$subquery->toSql()}) as t1"))->mergeBindings($subquery)->...->get();
</syntaxhighlight>
 
==Laravel Mix==
Laravel mix is an asset compiler/minifier for Laravel which uses webpack.<br>
Your configuration will be in <code>webpack.mix.js</code><br>
The following may be convenient:
<syntaxhighlight lang="js">
const fs = require('fs-extra');
class Rm {
    name() {
        return "rm";
    }
    register(to) {
        fs.removeSync(to);
    }
}
mix.extend('rm', new Rm());
</syntaxhighlight>
 
==JavaScript==
===Passing variables from PHP to JavaScript===
Variables can be passed from PHP to JS using view replacement. Note that while your JS is typically separate from your view, you will need to include some JS in your view to use this feature.<br>
[https://stackoverflow.com/questions/30074107/laravel-5-passing-variable-to-javascript/46805484 Example].
 
==Deployment==
===Directly===
Point your webserver with PHP to the public folder.<br>
If your application is publically accessible, make sure APP_DEBUG is set to false.
 
===Docker===
See the example Dockerfile below:
<syntaxhighlight lang="Dockerfile">
# Dockerfile
FROM php:8.1-apache
RUN apt-get update && \
    apt-get install -y nodejs npm zip libpq-dev sudo && \
    a2enmod rewrite
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
ENV APACHE_DOCUMENT_ROOT /var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
RUN sed -i 's#AllowOverride [Nn]one#AllowOverride All#' /etc/apache2/apache2.conf
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# RUN sed -i 's#upload_max_filesize = 2M#upload_max_filesize = 200M#' "$PHP_INI_DIR/php.ini"
# RUN sed -i 's#post_max_size = 8M#post_max_size = 200M#' "$PHP_INI_DIR/php.ini"
RUN chown www-data:www-data /var/www -R
ADD package.json package-lock.json /var/www/html/
RUN sudo -u www-data npm ci
ADD composer.json composer.lock artisan /var/www/html/
ADD app /var/www/html/app
ADD config /var/www/html/config
ADD database /var/www/html/database
ADD bootstrap /var/www/html/bootstrap
ADD routes /var/www/html/routes
RUN composer install
# Add remaining files
ADD . /var/www/html/
RUN cp .env.prod.example .env
RUN chmod 775 /root && \
    chown www-data:www-data -R /var/www/html && \
    npm run prod
</syntaxhighlight>
 
==Security==
===Vulnerabilities===
* [https://nvd.nist.gov/vuln/detail/CVE-2021-3129 CVE-2021-3129] - In Laravel < 8.4.2, leaving debug mode on can lead to remote execution.
 
==Resources==
* [https://laravel.com/docs/ Laravel Documentation]
* [https://laravel.com/docs/ Laravel Documentation]
* [https://laracasts.com/series/laravel-from-scratch-2018 Laravel from Scratch online course]
* [https://laracasts.com/series/laravel-from-scratch-2018 Laravel 5.7 From Scratch by Jeffrey Way]
* [https://laracasts.com/series/laravel-6-from-scratch Laravel 6 From Scratch by Jeffrey Way]
* [https://laracasts.com/series/blade-component-cookbook Blade Component Cookbook]

Latest revision as of 17:05, 15 December 2022

Laravel is a popular MVC framework for PHP.
One of the best parts of Laravel is their excellent video course on web development. The course is published on Laracasts.

Usage

Installation

composer global require laravel/installer

Creating a new project

Run the following commands.
Initialize a laravel project then cd into your project folder and install all php and node dependencies.
Then point your webserver to your project's public folder or run php artisan serve to start a local development server.

laravel new my-project
# Equivalent to
# composer create-project --prefer-dist laravel/laravel my-project
cd my-project
composer install
npm install

Copying an existing project

After you git pull an existing project, you will need to do the following to get it running.
Note: The app key is used for encrypting cookies.
Users will lose their session if the app key is regenerated in production.

composer install
npm ci
cp .env.example .env
# Fill in the .env config variables such as database, mail server, API keys, ...
php artisan key:generate
# Use npm run prod for production
npm run dev

Blade

Components

Note: Components were completely revamped in Laravel 7.

If you don't know anything watch Blade Component Cookbook or read the Blade Templates.

Components in Laravel 7 have two parts:

  • A php script in app/View/Components. E.g. MyComponent.php
  • A blade template in resources/views/components. E.g. my-component.blade.php

To get started, run:

php artisan make:component Alert

Controllers

Documentation
Controllers handle requests. The route file associates entry points with controller methods.
To make a controller, run php artisan make:controller <name of controller>.
Add the -r flag to automatically add REST methods.

Routing

Routing is handled in the routes/web.php file.
Documentation

RESTful

Note that for put, patch, delete you will need @method('PATCH') in your form html element.
Or you can use an ajax request via fetch or jQuery.

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

Theses can also be simplified with a single Route::resource($uri, $className); for a resource controller

Parameters/Variables

Route::get('user/{id}', function ($id) {
    return 'User '.$id;
});

Database

Query Builder

From subquery
$subquery = DB::connection('bayarea')->table(DB::raw("restaurants x, parking y"))
  ->select("x.id as id1", "y.id as id2")->where("x.id", "=", $restaurant_id);
$mainquery = DB::connection('bayarea')->table(DB::raw("({$subquery->toSql()}) as t1"))->mergeBindings($subquery)->...->get();

Laravel Mix

Laravel mix is an asset compiler/minifier for Laravel which uses webpack.
Your configuration will be in webpack.mix.js
The following may be convenient:

const fs = require('fs-extra');
class Rm {
    name() {
        return "rm";
    }
    register(to) {
        fs.removeSync(to);
    }
}
mix.extend('rm', new Rm());

JavaScript

Passing variables from PHP to JavaScript

Variables can be passed from PHP to JS using view replacement. Note that while your JS is typically separate from your view, you will need to include some JS in your view to use this feature.
Example.

Deployment

Directly

Point your webserver with PHP to the public folder.
If your application is publically accessible, make sure APP_DEBUG is set to false.

Docker

See the example Dockerfile below:

# Dockerfile
FROM php:8.1-apache
RUN apt-get update && \
    apt-get install -y nodejs npm zip libpq-dev sudo && \
    a2enmod rewrite
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
ENV APACHE_DOCUMENT_ROOT /var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
RUN sed -i 's#AllowOverride [Nn]one#AllowOverride All#' /etc/apache2/apache2.conf
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# RUN sed -i 's#upload_max_filesize = 2M#upload_max_filesize = 200M#' "$PHP_INI_DIR/php.ini"
# RUN sed -i 's#post_max_size = 8M#post_max_size = 200M#' "$PHP_INI_DIR/php.ini"
RUN chown www-data:www-data /var/www -R
ADD package.json package-lock.json /var/www/html/
RUN sudo -u www-data npm ci
ADD composer.json composer.lock artisan /var/www/html/
ADD app /var/www/html/app
ADD config /var/www/html/config
ADD database /var/www/html/database
ADD bootstrap /var/www/html/bootstrap
ADD routes /var/www/html/routes
RUN composer install
# Add remaining files
ADD . /var/www/html/ 
RUN cp .env.prod.example .env
RUN chmod 775 /root && \
    chown www-data:www-data -R /var/www/html && \
    npm run prod

Security

Vulnerabilities

  • CVE-2021-3129 - In Laravel < 8.4.2, leaving debug mode on can lead to remote execution.

Resources