Table of Contents
What is query scope?
Local query scope
Global query scope
#How to create a global query scope
#Apply global query scope
#Anonymous global query scope
#Ignore global query scope
#Precautions for global query scope
Test local query scope
Test range in controller
Conclusion
Home Backend Development PHP Tutorial Learn to master Query Scopes in Laravel

Learn to master Query Scopes in Laravel

Mar 06, 2025 am 02:28 AM

<p><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/174119929536701.jpg" class="lazy" alt="Learn to master Query Scopes in Laravel"></p> <p>When building a Laravel application, you may need to write queries with constraints that are used in multiple places throughout the application. Maybe you are building a multi-tenant application and you have to constantly add <code>where</code> constraints to the query to filter by user's team. Or maybe you are building a blog and you have to constantly add <code>where</code> constraints to the query to filter if the blog post has been published. </p> <p>In Laravel, we can use query scopes to help us keep these constraints neatly in one place and reuse them. </p> <p>In this article, we will study the local query scope and the global query scope. We will learn the difference between the two, how to create your own query scope, and how to write tests for them. </p> <p>After reading this article, you should be able to use query scopes confidently in your Laravel application. </p> <h1 id="What-is-query-scope">What is query scope? </h1> <hr> <p>Query scope allows you to define constraints in Eloquent queries in a reusable way. They are usually defined as methods on the Laravel model, or as classes that implement <code>IlluminateDatabaseEloquentScope</code> interfaces. </p> <p> Not only are they ideal for defining reusable logic in one place, but they can also make your code more readable by hiding complex query constraints after simple function calls. </p> <p>Query ranges are divided into two types: </p> <ul> <li>Local Query Ranges - You must manually apply these ranges to your query. </li> <li>Global Query Scopes - By default, these ranges are applied to all queries on the model, provided that the query is registered. </li> </ul> <p>If you have ever used the "soft delete" feature built in Laravel, you may have used the query scope unknowingly. Laravel uses local query scope to provide you with methods like <code>withTrashed</code> and <code>onlyTrashed</code> on the model. It also uses the global query scope to automatically add <code>whereNull('deleted_at')</code> constraints to all queries on the model so that soft deleted records are not returned by default in the query. </p> <p>Let's see how to create and use local query scopes and global query scopes in a Laravel application. </p> <h1 id="Local-query-scope">Local query scope</h1> <hr> <p> Local query scope is defined as a method on the Eloquent model, allowing you to define constraints that can be applied manually to model queries. </p> <p>Suppose we are building a blog application with an admin panel. In the admin panel, we have two pages: one for listing published blog posts and the other for listing unpublished blog posts. </p> <p>We assume that the blog post is accessed using the <code>AppModelsArticle</code> model and that the database table has an empty <code>published_at</code> column to store the publishing time of the blog post. If <code>published_at</code> is listed in the past, the blog post is considered to have been published. If <code>published_at</code> is listed in the future or is <code>null</code>, the blog post is deemed to be unpublished. </p> <p>To obtain published blog posts, we can write the following query: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>use App\Models\Article; $publishedPosts = Article::query() ->where('published_at', '<', now()) ->get();</code></pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <p>To obtain unpublished blog posts, we can write the following query: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>use App\Models\Article; use Illuminate\Contracts\Database\Eloquent\Builder; $unpublishedPosts = Article::query() ->where(function (Builder $query): void { $query->whereNull('published_at') ->orWhere('published_at', '>', now()); }) ->get();</code></pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <p>The above query is not particularly complicated. But, suppose we use them in multiple places throughout the application. As the number of occurrences increases, the possibility of us making mistakes or forgetting to update the query in one place is increasing. For example, developers may accidentally use <code>>=</code> instead of <code><</code> to query published blog posts. Alternatively, the logic to determine if a blog post has been published may change and we need to update all queries. </p> <p>This is where query scopes are very useful. So let's organize our queries by creating a local query scope on the <code>AppModelsArticle</code> model. </p> <p> Local query scopes are defined by creating a method that starts with <code>scope</code> and ends with the expected name of the scope. For example, a method named <code>scopePublished</code> will create a <code>published</code> range on the model. This method should accept an <code>IlluminateContractsDatabaseEloquentBuilder</code> instance and return a <code>IlluminateContractsDatabaseEloquentBuilder</code> instance. </p> <p>We add both ranges to the <code>AppModelsArticle</code> model: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>declare(strict_types=1); namespace App\Models; use Illuminate\Contracts\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; final class Article extends Model { public function scopePublished(Builder $query): Builder { return $query->where('published_at', '<', now()); } public function scopeNotPublished(Builder $query): Builder { return $query->where(function (Builder $query): Builder { return $query->whereNull('published_at') ->orWhere('published_at', '>', now()); }); } // ... }</code> </p> <p> As we saw in the example above, we moved the <code>where</code> constraint from the previous query into two separate methods: <code>scopePublished</code> and <code>scopeNotPublished</code>. We can now use these ranges in our query like this: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>use App\Models\Article; $publishedPosts = Article::query() ->published() ->get(); $unpublishedPosts = Article::query() ->notPublished() ->get();</code></pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <p>In my personal opinion, I find these queries easier to read and understand. This also means that if we need to write any query with the same constraints in the future, we can reuse these scopes. </p> <h1 id="Global-query-scope">Global query scope</h1> <hr> <p>Global query scope performs functions similar to local query scope. However, it is not applied manually on a query-by-query basis, but automatically applies to all queries on the model. </p> <p> As we mentioned earlier, Laravel's built-in "soft delete" function uses <code>IlluminateDatabaseEloquentSoftDeletingScope</code> global query scope. This range automatically adds <code>whereNull('deleted_at')</code> constraints to all queries on the model. If you are interested in understanding how it works, you can check out the source code on GitHub here. </p> <p>For example, suppose you are building a multi-tenant blog application with an admin panel. You may just want to allow users to view articles that belong to their team. So you might write a query like this: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>use App\Models\Article; $publishedPosts = Article::query() ->where('published_at', '<', now()) ->get();</code></pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <p>This query is good, but it's easy to forget to add <code>where</code> constraints. If you are writing another query and forgetting to add constraints, you will end up with an error in your application that will allow the user to interact with articles that are not part of their team. Of course, we don't want this to happen! </p> <p>To prevent this, we can create a global scope that we can automatically apply to all our <code>AppModelArticle</code> model queries. </p> <h3 id="How-to-create-a-global-query-scope">#How to create a global query scope</h3> <p> Let's create a global query scope that filters all queries by the <code>team_id</code> column. </p> <p> Please note that for the purposes of this article, we keep the example simple. In a real-life application, you may want to use a more powerful approach to dealing with situations like the user is not authenticated or the user belongs to multiple teams. But for now, let's keep it simple so we can focus on the concept of global query scope. </p> <p>We will first run the following Artisan command in the terminal: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>use App\Models\Article; use Illuminate\Contracts\Database\Eloquent\Builder; $unpublishedPosts = Article::query() ->where(function (Builder $query): void { $query->whereNull('published_at') ->orWhere('published_at', '>', now()); }) ->get();</code></pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <p> This should have created a new <code>app/Models/Scopes/TeamScope.php</code> file. We will make some updates to this file and then look at the finished code: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>declare(strict_types=1); namespace App\Models; use Illuminate\Contracts\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; final class Article extends Model { public function scopePublished(Builder $query): Builder { return $query->where('published_at', '<', now()); } public function scopeNotPublished(Builder $query): Builder { return $query->where(function (Builder $query): Builder { return $query->whereNull('published_at') ->orWhere('published_at', '>', now()); }); } // ... }</code></pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <p> In the above code example we can see that we have a new class that implements the <code>IlluminateDatabaseEloquentScope</code> interface and has a single method called <code>apply</code>. This is how we define the constraints to apply to model queries. </p> <p>Our global scope is now available. We can add this to any model we want to narrow the query to the user team. </p> <p>Let's apply it to the <code>AppModelsArticle</code> model. </p> <h3 id="Apply-global-query-scope">#Apply global query scope</h3> <p>There are several ways to apply the global scope to the model. The first method is to use the <code>IlluminateDatabaseEloquentAttributesScopedBy</code> attribute on the model: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>use App\Models\Article; $publishedPosts = Article::query() ->published() ->get(); $unpublishedPosts = Article::query() ->notPublished() ->get();</code></pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <p> Another method is to use <code>booted</code> method in the model's <code>addGlobalScope</code> method: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>use App\Models\Article; $articles = Article::query() ->where('team_id', Auth::user()->team_id) ->get();</code></pre><div class="contentsignin">Copy after login</div></div> <p> Both methods apply the <code>where('team_id', Auth::user()->team_id)</code> constraints to all queries on the <code>AppModelsArticle</code> model. </p> <p> This means you can now write queries without worrying about filtering by <code>team_id</code> column: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>php artisan make:scope TeamScope</code></pre><div class="contentsignin">Copy after login</div></div> <p>If we assume that the user belongs to a team with <code>team_id</code> being <code>1</code>, the following SQL will be generated for the above query: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>declare(strict_types=1); namespace App\Models\Scopes; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Scope; use Illuminate\Support\Facades\Auth; final readonly class TeamScope implements Scope { /** * Apply the scope to a given Eloquent query builder. */ public function apply(Builder $builder, Model $model): void { $builder->where('team_id', Auth::user()->team_id); } }</code></pre><div class="contentsignin">Copy after login</div></div> <p>This is cool, right? ! </p> <h3 id="Anonymous-global-query-scope">#Anonymous global query scope</h3> <p> Another way to define and apply a global query scope is to use an anonymous global scope. </p> <p>Let's update our <code>AppModelsArticle</code> model to use anonymous global scope: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>declare(strict_types=1); namespace App\Models; use App\Models\Scopes\TeamScope; use Illuminate\Database\Eloquent\Attributes\ScopedBy; use Illuminate\Database\Eloquent\Model; #[ScopedBy(TeamScope::class)] final class Article extends Model { // ... }</code></pre><div class="contentsignin">Copy after login</div></div> <p> In the above code example, we used the <code>addGlobalScope</code> method to define anonymous global scope in the <code>booted</code> method of the model. <code>addGlobalScope</code> method accepts two parameters: </p> <ul> <li>The name of the scope - If you need to ignore it in your query, you can use this name to refer to the scope </li> <li>Scope Constraints - Define the closure to apply to the constraints </li> </ul> <p> As with other methods, this applies the <code>where('team_id', Auth::user()->team_id)</code> constraint to all queries on the <code>AppModelsArticle</code> model. </p> <p>In my experience, anonymous global scope is not as common as defining global scope in a separate class. But it is beneficial to know that they are available in case of emergencies. </p> <h3 id="Ignore-global-query-scope">#Ignore global query scope</h3> <p> Sometimes you may want to write a query that does not use the global query scope that has been applied to the model. For example, you might be building a report or analysis query that needs to contain all records regardless of the global query scope. </p> <p>If this is the case, you can use one of two methods to ignore the global scope. </p> <p>The first method is <code>withoutGlobalScopes</code>. This method allows you to ignore all global scopes on the model if no parameters are passed to it: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>use App\Models\Article; $publishedPosts = Article::query() ->where('published_at', '<', now()) ->get();</code></pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <p> Or, if you want to ignore only a given set of global scopes, you can pass the scope name to the <code>withoutGlobalScopes</code> method: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>use App\Models\Article; use Illuminate\Contracts\Database\Eloquent\Builder; $unpublishedPosts = Article::query() ->where(function (Builder $query): void { $query->whereNull('published_at') ->orWhere('published_at', '>', now()); }) ->get();</code></pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <p> In the example above, we ignore <code>AppModelsScopesTeamScope</code> and another fictional anonymous global scope called <code>another_scope</code>. </p> <p> Or, if you want to ignore only a single global scope, you can use the <code>withoutGlobalScope</code> method: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>declare(strict_types=1); namespace App\Models; use Illuminate\Contracts\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; final class Article extends Model { public function scopePublished(Builder $query): Builder { return $query->where('published_at', '<', now()); } public function scopeNotPublished(Builder $query): Builder { return $query->where(function (Builder $query): Builder { return $query->whereNull('published_at') ->orWhere('published_at', '>', now()); }); } // ... }</code></pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <h3 id="Precautions-for-global-query-scope">#Precautions for global query scope</h3> <p>It is important to remember that the global query scope is only applied to queries made through the model. If you write database queries using the <code>IlluminateSupportFacadesDB</code> appearance, the global query scope is not applied. </p> <p>For example, suppose you wrote this query and you want it to crawl only articles belonging to the team of logged in users: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>use App\Models\Article; $publishedPosts = Article::query() ->published() ->get(); $unpublishedPosts = Article::query() ->notPublished() ->get();</code></pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <p> In the above query, even if the global query scope of <code>AppModelsArticle</code> is defined on the <code>AppModelsScopesTeamScope</code> model, the scope will not be applied. Therefore, you need to make sure that constraints are applied manually in the database query. </p> <h1 id="Test-local-query-scope">Test local query scope</h1> <hr> <p> Now that we have learned how to create and use query scopes, we will look at how to write tests for them. </p> <p>There are several ways to test the scope of a query, and the method you choose may depend on your personal preference or the content of the scope you are writing. For example, you might want to write more unit-style tests for the scope. Alternatively, you might want to write more integration style tests that test scope in contexts like controllers. </p> <p> Personally, I like to mix the two so I can be sure that the scope is adding the correct constraints and that the scope is actually being used in the query. </p> <p>Let's start with the previous examples <code>published</code> and <code>notPublished</code> ranges and write some tests for them. We will need to write two different tests (one for each range): </p> <ul> <li>A test check<code>published</code> range returns only published articles. </li> <li>A test check<code>notPublished</code> range returns only unpublished articles. </li> </ul> <p>Let's look at these tests and then discuss what's being done: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>use App\Models\Article; $publishedPosts = Article::query() ->where('published_at', '<', now()) ->get();</code></pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <p> We can see in the above test file, we first create some data in the <code>setUp</code> method. We have created two published articles, one unscheduled article and one arranged article. </p> <p> Then there is a test (<code>only_published_articles_are_returned</code>) that checks the <code>published</code> range to return only published articles. There is also a test (<code>only_not_published_articles_are_returned</code>) that checks the <code>notPublished</code> range to return only unpublished articles. </p> <p> By doing this, we can now be sure that our query scope is applying constraints as expected. </p> <h1 id="Test-range-in-controller">Test range in controller</h1> <hr> <p>As we mentioned, another way to test the scope of a query is to test them in the context used in the controller. While the isolation testing of scopes can help assert that scope is adding the correct constraints to the query, it doesn't actually test whether the scope is used in the application as expected. For example, you might forget to add a <code>published</code> range to a query in the controller method. </p> <p> These types of errors can be captured by writing tests that asserts that return correct data when using scopes in controller methods. </p> <p> Let's take the example of having a multi-tenant blog application and write a test for the controller method that lists the articles. Let's assume we have a very simple controller method, as follows: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>use App\Models\Article; use Illuminate\Contracts\Database\Eloquent\Builder; $unpublishedPosts = Article::query() ->where(function (Builder $query): void { $query->whereNull('published_at') ->orWhere('published_at', '>', now()); }) ->get();</code></pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <p>We assume that the <code>AppModelsArticle</code> model has applied our <code>AppModelsScopesTeamScope</code>. </p> <p>We will assert that we only return articles that belong to the user team. The test case might look like this: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><code>declare(strict_types=1); namespace App\Models; use Illuminate\Contracts\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; final class Article extends Model { public function scopePublished(Builder $query): Builder { return $query->where('published_at', '<', now()); } public function scopeNotPublished(Builder $query): Builder { return $query->where(function (Builder $query): Builder { return $query->whereNull('published_at') ->orWhere('published_at', '>', now()); }); } // ... }</code></pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <p>In the above test, we are creating two teams. Then, we create a user belonging to Team One. We created 3 articles for Team 1 and 2 articles for Team 2. We then act as users and make a request to the controller method that lists the articles. The controller method should return only 3 articles belonging to Team One, so we assert that only those articles are returned by comparing the article IDs. </p> <p> This means we can be sure that the global query scope is being used as expected in the controller method. </p> <h1 id="Conclusion">Conclusion</h1> <hr> <p>In this article, we have learned about local query scope and global query scope. We learned the differences between them, how to create and use them, and how to write tests for them. </p> <p>Hope you should now be able to use query scopes confidently in your Laravel application. </p>

The above is the detailed content of Learn to master Query Scopes in Laravel. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
1 months ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
1 months ago By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers Of The Witch Tree - How To Unlock The Grappling Hook
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1677
14
PHP Tutorial
1280
29
C# Tutorial
1257
24
Explain secure password hashing in PHP (e.g., password_hash, password_verify). Why not use MD5 or SHA1? Explain secure password hashing in PHP (e.g., password_hash, password_verify). Why not use MD5 or SHA1? Apr 17, 2025 am 12:06 AM

In PHP, password_hash and password_verify functions should be used to implement secure password hashing, and MD5 or SHA1 should not be used. 1) password_hash generates a hash containing salt values ​​to enhance security. 2) Password_verify verify password and ensure security by comparing hash values. 3) MD5 and SHA1 are vulnerable and lack salt values, and are not suitable for modern password security.

How does PHP type hinting work, including scalar types, return types, union types, and nullable types? How does PHP type hinting work, including scalar types, return types, union types, and nullable types? Apr 17, 2025 am 12:25 AM

PHP type prompts to improve code quality and readability. 1) Scalar type tips: Since PHP7.0, basic data types are allowed to be specified in function parameters, such as int, float, etc. 2) Return type prompt: Ensure the consistency of the function return value type. 3) Union type prompt: Since PHP8.0, multiple types are allowed to be specified in function parameters or return values. 4) Nullable type prompt: Allows to include null values ​​and handle functions that may return null values.

PHP and Python: Different Paradigms Explained PHP and Python: Different Paradigms Explained Apr 18, 2025 am 12:26 AM

PHP is mainly procedural programming, but also supports object-oriented programming (OOP); Python supports a variety of paradigms, including OOP, functional and procedural programming. PHP is suitable for web development, and Python is suitable for a variety of applications such as data analysis and machine learning.

Choosing Between PHP and Python: A Guide Choosing Between PHP and Python: A Guide Apr 18, 2025 am 12:24 AM

PHP is suitable for web development and rapid prototyping, and Python is suitable for data science and machine learning. 1.PHP is used for dynamic web development, with simple syntax and suitable for rapid development. 2. Python has concise syntax, is suitable for multiple fields, and has a strong library ecosystem.

PHP and Python: A Deep Dive into Their History PHP and Python: A Deep Dive into Their History Apr 18, 2025 am 12:25 AM

PHP originated in 1994 and was developed by RasmusLerdorf. It was originally used to track website visitors and gradually evolved into a server-side scripting language and was widely used in web development. Python was developed by Guidovan Rossum in the late 1980s and was first released in 1991. It emphasizes code readability and simplicity, and is suitable for scientific computing, data analysis and other fields.

PHP and Frameworks: Modernizing the Language PHP and Frameworks: Modernizing the Language Apr 18, 2025 am 12:14 AM

PHP remains important in the modernization process because it supports a large number of websites and applications and adapts to development needs through frameworks. 1.PHP7 improves performance and introduces new features. 2. Modern frameworks such as Laravel, Symfony and CodeIgniter simplify development and improve code quality. 3. Performance optimization and best practices further improve application efficiency.

Why Use PHP? Advantages and Benefits Explained Why Use PHP? Advantages and Benefits Explained Apr 16, 2025 am 12:16 AM

The core benefits of PHP include ease of learning, strong web development support, rich libraries and frameworks, high performance and scalability, cross-platform compatibility, and cost-effectiveness. 1) Easy to learn and use, suitable for beginners; 2) Good integration with web servers and supports multiple databases; 3) Have powerful frameworks such as Laravel; 4) High performance can be achieved through optimization; 5) Support multiple operating systems; 6) Open source to reduce development costs.

PHP's Impact: Web Development and Beyond PHP's Impact: Web Development and Beyond Apr 18, 2025 am 12:10 AM

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

See all articles