SlideShare a Scribd company logo
Laravel SPAM
(Shengyou Fan)
PHP Day #56
2020/10/29
Photo by Pau Casals on Unsplash
— {
"name": "shengyou/self-introduction",
"description": "Self intro for PHP meetup",
"authors": [
{
"name": " (Shengyou Fan)",
"company": "JetBrains",
"role": "Developer Advocate",
"email": "shengyou.fan@jetbrains.com",
"homepage": "https://kraftsman.tw"
}
],
"support": {
"facebook": "https://fb.me/shengyoufan",
"telegram": "@shengyou",
"line": "shengyoufan"
}
}
Composer 2.0
—
$ composer self-update --2
!
Composer
—
Composer
2 Tips …
Tips
—
https://tw.intellij.tips https://tw.kotlin.tips
Web Laravel
PhpStorm
$ artisan make:migration
$ artisan migrate
class Create...Table extends Migration
{
public function up()
{
Schema::create('...', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email');
$table->string('mobile')->nullable();
$table->text('message');
$table->timestamps();
});
}
// ...
}
Migration
—
Model
—
class Feedback extends Model
{
use HasFactory;
protected $table = '...';
protected $fillable = [
'name',
'email',
'mobile',
'message',
];
protected $casts = [
'name' => 'string',
'email' => 'string',
'mobile' => 'string',
'message' => 'string',
];
}
$ artisan make:model
Factory
—
class FeedbackFactory extends Factory
{
protected $model = Feedback::class;
public function definition()
{
return [
'name' => $this->faker->name,
'email' => $this->faker->email,
'mobile' => $this->faker->phoneNumber,
'message' => $this->faker->sentence,
];
}
}
$ artisan make:factory
Seeder
—
class FeedbackSeeder extends Seeder
{
public function run()
{
Feedback::truncate();
Feedback::factory(10)->create();
}
}
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call(FeedbackSeeder::class);
}
}
$ artisan make:seeder
$ artisan db:seed
View
—
@if ($message = session()->get('success'))
<div>
{{ $message }}
</div>
@endisset
<form action="{{ route('contact.store') }}" method="POST">
@csrf
<div class="control-group form-group">
<div class="controls">
<label for="name"> </label>
<input type="text" class="form-control"
id="name" name="name"
value="{{ old('name') }}" required>
@error('name')
<p class="invalid-feedback">{{ $message }}</p>
@enderror
</div>
</div>
// ...
</form>
Form Request
—
class FeedbackRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|min:2|max:255',
'email' => 'required|email',
'mobile' => 'nullable|min:10|max:10',
'message' => 'required',
];
}
}
$ artisan make:request
Controller
—
class ContactController extends Controller
{
public function index()
{
return view('contact.index');
}
public function store(FeedbackRequest $request)
{
Feedback::create($request->all());
return redirect()->route('contact.index')
->with('success', '...');
}
}
$ artisan make:controller
Route
—
Route::get('contact', [ContactController::class, 'index'])
->name('contact.index');
Route::post('contact', [ContactController::class, 'store'])
->name('contact.store');
…
Photo by Hannes Johnson on Unsplash
…
!
Google
—
• Google Recaptcha
Recaptcha
—
v1 v2
josiasmontag/laravel-recaptchav3
—
ReCaptcha
—
www.google.com/recaptcha
/
—
// config/recaptchav3.php
return [
'origin' => env('RECAPTCHAV3_ORIGIN', ''),
'sitekey' => env('RECAPTCHAV3_SITEKEY', ''),
'secret' => env('RECAPTCHAV3_SECRET', '')
];
// .env
RECAPTCHAV3_SITEKEY=sitekey
RECAPTCHAV3_SECRET=secret
$ composer require
$ artisan vendor:publish
View
—
@section('page-script')
{!! RecaptchaV3::initJs() !!}
@endsection
@section('page-content')
<form action="{{ route('contact.store') }}" method="POST">
// ...
{!! RecaptchaV3::field('contact') !!}
// ...
@if ($errors->get('g-recaptcha-response'))
<p>{{ $errors->first('g-recaptcha-response') }}</p>
@endif
// ...
</form>
@endsection
Validation
—
// app/Http/Requests/FeedbackRequest.php
class FeedbackRequest extends FormRequest
{
public function rules()
{
return [
'name' => 'required|min:2|max:255',
'email' => 'required|email',
'mobile' => 'nullable|min:10|max:10',
'message' => 'required',
'g-recaptcha-response' => 'recaptchav3:contact,0.5'
];
}
}
// resources/lang/en/validation.php
'custom' => [
'g-recaptcha-response' => [
'recaptchav3' => '...',
],
],
Badge
—
@section('page-style')
<style>
.grecaptcha-badge { visibility: hidden; }
</style>
@endsection
@section('page-content')
This site is protected by ReCaptcha and the Google <a
href="https://policies.google.com/privacy">Privacy Policy</a>
and <a href="https://policies.google.com/terms">Terms of
Service</a> apply.
@endsection
…
—
• Google Recaptcha
• Honeypot
Honeypot
—
•
•
• CSS Honeypot
•
spatie/laravel-honeypot
—
/
—
return [
'name_field_name' => env('HONEYPOT_NAME', ‘my_name'),
'randomize_name_field_name' => env('...', true),
'valid_from_timestamp' => env('...', true),
'valid_from_field_name' => env('...', 'valid_from'),
'amount_of_seconds' => env('...', 1),
'respond_to_spam_with' => BlankPageResponder::class,
'honeypot_fields_required_for_all_forms' => false,
'enabled' => env('HONEYPOT_ENABLED', true),
];
$ composer require
$ artisan vendor:publish
View
—
<form action="{{ route('contact.store') }}" method="POST">
// ...
@honeypot
// ...
</form>
Route
—
Route::post('contact', [ContactController::class, 'store'])
->middleware(ProtectAgainstSpam::class)
->name('contact.store');
—
return [
// ...
'amount_of_seconds' => env('...', 5),
// ...
];
—
return [
'respond_to_spam_with' => SpamPageResponder::class,
];
Responder
—
class SpamPageResponder implements SpamResponder
{
public function respond(Request $request, Closure $next)
{
return response()->view('spam.index');
}
}
( _ )
—
• Google Recaptcha
• Honeypot
• Akismet
Akismet
—
• Wordpress SPAM
•
https://akismet.com/
nickurt/laravel-akismet
—
/
—
// config/akismet.php
return [
'api_key' => env('AKISMET_APIKEY', ''),
'blog_url' => env('AKISMET_BLOGURL', null),
];
// .env
AKISMET_APIKEY=my_akismet_api_key
AKISMET_BLOGURL=http://site_url
$ composer require
$ artisan vendor:publish
View
—
<input type="hidden" name="akismet" value="akismet">
@error('akismet')
<p class="invalid-feedback">{{ $message }}</p>
@enderror
Form Request
—
class FeedbackRequest extends FormRequest
{
// ...
public function rules()
{
return [
'name' => 'required|min:2|max:255',
'email' => 'required|email',
'mobile' => 'nullable|min:10|max:10',
'message' => 'required',
'akismet' => [new AkismetRule(
request()->input('email'),
request()->input('name')
)]
];
}
}
API
"
—
// Migration
Schema::table('feedback', function (Blueprint $table) {
$table->boolean('flag_as_spam')
->default(false)
->after('message');
});
// Model
class Feedback extends Model
{
protected $fillable = [
// ...
'flag_as_spam',
];
protected $casts = [
// ...
'flag_as_spam' => 'boolean',
];
}
$ artisan create:migration
Service
—
class AkismetDetectionService
{
private $akismet;
public function __construct(Akismet $akismet)
{
$this->akismet = $akismet;
}
public function checkContactMessage(
string $name, string $email, string $message
): bool {
if ($this->akismet->validateKey()) {
$this->akismet->setCommentType('contact-form')
->setCommentAuthor($name)
->setCommentAuthorEmail($email)
->setCommentContent($message);
return $this->akismet->isSpam();
}
return true;
}
}
Controller
—
class ContactController extends Controller
{
public function store(
FeedbackRequest $request,
AkismetDetectionService $akismet
) {
$spamDetectResult = $akismet->checkContactMessage(
$request->input('name'),
$request->input('email'),
$request->input('message'),
);
$attributes = array_merge(
$request->only(['name', 'email', ‘message']),
['flag_as_spam' => $spamDetectResult]
);
Feedback::create($attributes);
// ...
}
}
Stop Forum Spam
—
• SPAM
• username email IP…
https://www.stopforumspam.com
nickurt/laravel-stopforumspam
—
—
•
• SPAM SPAM
• SPAM
…
"
…
#
$
xxxxxxxxxxxxx@gnail.com
yyyyyyy@qq.con
cccccccccc@yahoo.comn
zzzzzz@164.com
aaaaaaaaaaa@gmail.cm
wwwww@hotmaiI.com
xxxxxxxxxxxxx@gnail.com
yyyyyyy@qq.con
cccccccccc@yahoo.comn
zzzzzz@164.com
aaaaaaaaaaa@gmail.cm
wwwww@hotmaiI.com
Email
Photo by Tobias Tullius on Unsplash
intellij.tips
JetBrains
—
—
Shengyou Fan ( )
shengyou.fan@jetbrains.com
Q&A
—
Laravel SPAM

More Related Content

What's hot

Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)True-Vision
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
Triple Blitz Strike
Triple Blitz StrikeTriple Blitz Strike
Triple Blitz Strike
Denis Zhdanov
 
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other ToolsCool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Ryan Weaver
 
Using Ansible as Makefiles to unite your developers
Using Ansible as Makefiles to unite your developersUsing Ansible as Makefiles to unite your developers
Using Ansible as Makefiles to unite your developers
thiagoalessio
 
Developing apps using Perl
Developing apps using PerlDeveloping apps using Perl
Developing apps using Perl
Anatoly Sharifulin
 
Write php deploy everywhere
Write php deploy everywhereWrite php deploy everywhere
Write php deploy everywhere
Michelangelo van Dam
 
Lights, Camera, Docker: Streaming Video at DramaFever
Lights, Camera, Docker: Streaming Video at DramaFeverLights, Camera, Docker: Streaming Video at DramaFever
Lights, Camera, Docker: Streaming Video at DramaFever
bridgetkromhout
 
Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Masahiro Nagano
 
Testing your infrastructure with litmus
Testing your infrastructure with litmusTesting your infrastructure with litmus
Testing your infrastructure with litmus
Bram Vogelaar
 
Node.js Express
Node.js  ExpressNode.js  Express
Node.js Express
Eyal Vardi
 
Inside Bokete: Web Application with Mojolicious and others
Inside Bokete:  Web Application with Mojolicious and othersInside Bokete:  Web Application with Mojolicious and others
Inside Bokete: Web Application with Mojolicious and others
Yusuke Wada
 
MeaNstack on Docker
MeaNstack on DockerMeaNstack on Docker
MeaNstack on Docker
Daniel Ku
 
HTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & socketsHTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & sockets
Remy Sharp
 
Composer
ComposerComposer
Composer
Tom Corrigan
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Rack
sickill
 
Express JS
Express JSExpress JS
Express JS
Designveloper
 
Integration Test Cucumber + Webrat + Selenium
Integration Test Cucumber + Webrat + SeleniumIntegration Test Cucumber + Webrat + Selenium
Integration Test Cucumber + Webrat + Seleniumtka
 

What's hot (20)

Plack - LPW 2009
Plack - LPW 2009Plack - LPW 2009
Plack - LPW 2009
 
Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Triple Blitz Strike
Triple Blitz StrikeTriple Blitz Strike
Triple Blitz Strike
 
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other ToolsCool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
 
Using Ansible as Makefiles to unite your developers
Using Ansible as Makefiles to unite your developersUsing Ansible as Makefiles to unite your developers
Using Ansible as Makefiles to unite your developers
 
Developing apps using Perl
Developing apps using PerlDeveloping apps using Perl
Developing apps using Perl
 
Write php deploy everywhere
Write php deploy everywhereWrite php deploy everywhere
Write php deploy everywhere
 
Lights, Camera, Docker: Streaming Video at DramaFever
Lights, Camera, Docker: Streaming Video at DramaFeverLights, Camera, Docker: Streaming Video at DramaFever
Lights, Camera, Docker: Streaming Video at DramaFever
 
Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7
 
Testing your infrastructure with litmus
Testing your infrastructure with litmusTesting your infrastructure with litmus
Testing your infrastructure with litmus
 
Write php deploy everywhere tek11
Write php deploy everywhere   tek11Write php deploy everywhere   tek11
Write php deploy everywhere tek11
 
Node.js Express
Node.js  ExpressNode.js  Express
Node.js Express
 
Inside Bokete: Web Application with Mojolicious and others
Inside Bokete:  Web Application with Mojolicious and othersInside Bokete:  Web Application with Mojolicious and others
Inside Bokete: Web Application with Mojolicious and others
 
MeaNstack on Docker
MeaNstack on DockerMeaNstack on Docker
MeaNstack on Docker
 
HTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & socketsHTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & sockets
 
Composer
ComposerComposer
Composer
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Rack
 
Express JS
Express JSExpress JS
Express JS
 
Integration Test Cucumber + Webrat + Selenium
Integration Test Cucumber + Webrat + SeleniumIntegration Test Cucumber + Webrat + Selenium
Integration Test Cucumber + Webrat + Selenium
 

Similar to [PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史

Django - Framework web para perfeccionistas com prazos
Django - Framework web para perfeccionistas com prazosDjango - Framework web para perfeccionistas com prazos
Django - Framework web para perfeccionistas com prazos
Igor Sobreira
 
Spca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_librariesSpca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_librariesNCCOMMS
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
Yusuke Wada
 
Mitigate Maliciousness -- jQuery Europe 2013
Mitigate Maliciousness -- jQuery Europe 2013Mitigate Maliciousness -- jQuery Europe 2013
Mitigate Maliciousness -- jQuery Europe 2013
Mike West
 
Intro to Php Security
Intro to Php SecurityIntro to Php Security
Intro to Php Security
Dave Ross
 
FamilySearch Reference Client
FamilySearch Reference ClientFamilySearch Reference Client
FamilySearch Reference Client
Dallan Quass
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and Python
PiXeL16
 
Presentation html5 css3 by thibaut
Presentation html5 css3 by thibautPresentation html5 css3 by thibaut
Presentation html5 css3 by thibaut
Thibaut Baillet
 
LaravelConf Taiwan 2018 套件發表會 - 飛信資訊 SMTP 及 SMS SDK
LaravelConf Taiwan 2018 套件發表會 - 飛信資訊 SMTP 及 SMS SDKLaravelConf Taiwan 2018 套件發表會 - 飛信資訊 SMTP 及 SMS SDK
LaravelConf Taiwan 2018 套件發表會 - 飛信資訊 SMTP 及 SMS SDK
Shengyou Fan
 
Bootstrap 3 in Joomla!
Bootstrap 3 in Joomla!Bootstrap 3 in Joomla!
Bootstrap 3 in Joomla!
Hans Kuijpers
 
Simple Web Apps With Sinatra
Simple Web Apps With SinatraSimple Web Apps With Sinatra
Simple Web Apps With Sinatraa_l
 
Private slideshow
Private slideshowPrivate slideshow
Private slideshowsblackman
 
Ruby gems
Ruby gemsRuby gems
Ruby gems
Papp Laszlo
 
Survey of Front End Topics in Rails
Survey of Front End Topics in RailsSurvey of Front End Topics in Rails
Survey of Front End Topics in RailsBenjamin Vandgrift
 
Evolution Of Web Security
Evolution Of Web SecurityEvolution Of Web Security
Evolution Of Web Security
Chris Shiflett
 
Ams adapters
Ams adaptersAms adapters
Ams adapters
Bruno Alló Bacarini
 
PHP SA 2014 - Releasing Your Open Source Project
PHP SA 2014 - Releasing Your Open Source ProjectPHP SA 2014 - Releasing Your Open Source Project
PHP SA 2014 - Releasing Your Open Source Project
xsist10
 
Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)
Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)
Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)
Dotan Dimet
 

Similar to [PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史 (20)

Django - Framework web para perfeccionistas com prazos
Django - Framework web para perfeccionistas com prazosDjango - Framework web para perfeccionistas com prazos
Django - Framework web para perfeccionistas com prazos
 
Spca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_librariesSpca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_libraries
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
 
Mitigate Maliciousness -- jQuery Europe 2013
Mitigate Maliciousness -- jQuery Europe 2013Mitigate Maliciousness -- jQuery Europe 2013
Mitigate Maliciousness -- jQuery Europe 2013
 
Intro to Php Security
Intro to Php SecurityIntro to Php Security
Intro to Php Security
 
FamilySearch Reference Client
FamilySearch Reference ClientFamilySearch Reference Client
FamilySearch Reference Client
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and Python
 
Presentation html5 css3 by thibaut
Presentation html5 css3 by thibautPresentation html5 css3 by thibaut
Presentation html5 css3 by thibaut
 
LaravelConf Taiwan 2018 套件發表會 - 飛信資訊 SMTP 及 SMS SDK
LaravelConf Taiwan 2018 套件發表會 - 飛信資訊 SMTP 及 SMS SDKLaravelConf Taiwan 2018 套件發表會 - 飛信資訊 SMTP 及 SMS SDK
LaravelConf Taiwan 2018 套件發表會 - 飛信資訊 SMTP 及 SMS SDK
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
 
Bootstrap 3 in Joomla!
Bootstrap 3 in Joomla!Bootstrap 3 in Joomla!
Bootstrap 3 in Joomla!
 
Simple Web Apps With Sinatra
Simple Web Apps With SinatraSimple Web Apps With Sinatra
Simple Web Apps With Sinatra
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
Private slideshow
Private slideshowPrivate slideshow
Private slideshow
 
Ruby gems
Ruby gemsRuby gems
Ruby gems
 
Survey of Front End Topics in Rails
Survey of Front End Topics in RailsSurvey of Front End Topics in Rails
Survey of Front End Topics in Rails
 
Evolution Of Web Security
Evolution Of Web SecurityEvolution Of Web Security
Evolution Of Web Security
 
Ams adapters
Ams adaptersAms adapters
Ams adapters
 
PHP SA 2014 - Releasing Your Open Source Project
PHP SA 2014 - Releasing Your Open Source ProjectPHP SA 2014 - Releasing Your Open Source Project
PHP SA 2014 - Releasing Your Open Source Project
 
Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)
Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)
Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)
 

More from Shengyou Fan

[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
Shengyou Fan
 
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
Shengyou Fan
 
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
Shengyou Fan
 
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
Shengyou Fan
 
How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023
Shengyou Fan
 
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
Shengyou Fan
 
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
Shengyou Fan
 
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
Shengyou Fan
 
Using the Exposed SQL Framework to Manage Your Database
Using the Exposed SQL Framework to Manage Your DatabaseUsing the Exposed SQL Framework to Manage Your Database
Using the Exposed SQL Framework to Manage Your Database
Shengyou Fan
 
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
Shengyou Fan
 
[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園
Shengyou Fan
 
初探 Kotlin Multiplatform
初探 Kotlin Multiplatform初探 Kotlin Multiplatform
初探 Kotlin Multiplatform
Shengyou Fan
 
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
Shengyou Fan
 
[PHP 也有 Day #64] PHP 升級指南
[PHP 也有 Day #64] PHP 升級指南[PHP 也有 Day #64] PHP 升級指南
[PHP 也有 Day #64] PHP 升級指南
Shengyou Fan
 
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
Shengyou Fan
 
老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具
Shengyou Fan
 
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
Shengyou Fan
 
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
Shengyou Fan
 
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
Shengyou Fan
 
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
Shengyou Fan
 

More from Shengyou Fan (20)

[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
 
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
[JCConf 2023] 從 Kotlin Multiplatform 到 Compose Multiplatform:在多平台間輕鬆共用業務邏輯與 U...
 
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
[Kotlin 讀書會第五梯次] 深入淺出 Kotlin 第一章導讀
 
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
[WebConf Taiwan 2023] 一份 Zend Engine 外帶!透過 Micro 讓一次打包、多處運行變得可能
 
How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023How I make a podcast website using serverless technology in 2023
How I make a podcast website using serverless technology in 2023
 
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
[Effective Kotlin 讀書會] 第八章 Efficient collection processing 導讀
 
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
 
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
 
Using the Exposed SQL Framework to Manage Your Database
Using the Exposed SQL Framework to Manage Your DatabaseUsing the Exposed SQL Framework to Manage Your Database
Using the Exposed SQL Framework to Manage Your Database
 
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
[COSCUP 2022] 讓黑畫面再次偉大 - 用 PHP 寫 CLI 工具
 
[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園
 
初探 Kotlin Multiplatform
初探 Kotlin Multiplatform初探 Kotlin Multiplatform
初探 Kotlin Multiplatform
 
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
 
[PHP 也有 Day #64] PHP 升級指南
[PHP 也有 Day #64] PHP 升級指南[PHP 也有 Day #64] PHP 升級指南
[PHP 也有 Day #64] PHP 升級指南
 
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
以 Kotlin Multiplatform Mobile (KMM) 開發跨平台行動應用
 
老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具
 
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
 
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
[Kotlin Serverless 工作坊] 單元 3 - 實作 JSON API
 
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
 
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
[Kotlin Serverless 工作坊] 單元 1 - 開發環境建置
 

Recently uploaded

急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
3ipehhoa
 
BASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptxBASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptx
natyesu
 
Output determination SAP S4 HANA SAP SD CC
Output determination SAP S4 HANA SAP SD CCOutput determination SAP S4 HANA SAP SD CC
Output determination SAP S4 HANA SAP SD CC
ShahulHameed54211
 
ER(Entity Relationship) Diagram for online shopping - TAE
ER(Entity Relationship) Diagram for online shopping - TAEER(Entity Relationship) Diagram for online shopping - TAE
ER(Entity Relationship) Diagram for online shopping - TAE
Himani415946
 
1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...
JeyaPerumal1
 
This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!
nirahealhty
 
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shopHistory+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
laozhuseo02
 
Latest trends in computer networking.pptx
Latest trends in computer networking.pptxLatest trends in computer networking.pptx
Latest trends in computer networking.pptx
JungkooksNonexistent
 
The+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptxThe+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptx
laozhuseo02
 
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and GuidelinesMulti-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Sanjeev Rampal
 
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
3ipehhoa
 
How to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptxHow to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptx
Gal Baras
 
Living-in-IT-era-Module-7-Imaging-and-Design-for-Social-Impact.pptx
Living-in-IT-era-Module-7-Imaging-and-Design-for-Social-Impact.pptxLiving-in-IT-era-Module-7-Imaging-and-Design-for-Social-Impact.pptx
Living-in-IT-era-Module-7-Imaging-and-Design-for-Social-Impact.pptx
TristanJasperRamos
 
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
3ipehhoa
 
test test test test testtest test testtest test testtest test testtest test ...
test test  test test testtest test testtest test testtest test testtest test ...test test  test test testtest test testtest test testtest test testtest test ...
test test test test testtest test testtest test testtest test testtest test ...
Arif0071
 
guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...
Rogerio Filho
 

Recently uploaded (16)

急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
 
BASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptxBASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptx
 
Output determination SAP S4 HANA SAP SD CC
Output determination SAP S4 HANA SAP SD CCOutput determination SAP S4 HANA SAP SD CC
Output determination SAP S4 HANA SAP SD CC
 
ER(Entity Relationship) Diagram for online shopping - TAE
ER(Entity Relationship) Diagram for online shopping - TAEER(Entity Relationship) Diagram for online shopping - TAE
ER(Entity Relationship) Diagram for online shopping - TAE
 
1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...
 
This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!
 
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shopHistory+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
 
Latest trends in computer networking.pptx
Latest trends in computer networking.pptxLatest trends in computer networking.pptx
Latest trends in computer networking.pptx
 
The+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptxThe+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptx
 
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and GuidelinesMulti-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
 
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
 
How to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptxHow to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptx
 
Living-in-IT-era-Module-7-Imaging-and-Design-for-Social-Impact.pptx
Living-in-IT-era-Module-7-Imaging-and-Design-for-Social-Impact.pptxLiving-in-IT-era-Module-7-Imaging-and-Design-for-Social-Impact.pptx
Living-in-IT-era-Module-7-Imaging-and-Design-for-Social-Impact.pptx
 
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
 
test test test test testtest test testtest test testtest test testtest test ...
test test  test test testtest test testtest test testtest test testtest test ...test test  test test testtest test testtest test testtest test testtest test ...
test test test test testtest test testtest test testtest test testtest test ...
 
guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...
 

[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史