How to connect Laravel to SQL Server locally

If you want to set Laravel DB to be SQL Server, you need to edit .env file and add sqlsrv as your DB connection

DB_CONNECTION=sqlsrv
DB_HOST=127.0.0.1  
DB_PORT=1433
DB_DATABASE=YOUR_DB_NAME
DB_USERNAMEYOUR_USERNAME
DB_PASSWORD=YOUR_PASSWORD

You need to save the .env file and clear the config cache

php artisan config:clear

Also you need to download Microsoft Driver for PHP for SQLServer from this url:

https://learn.microsoft.com/en-us/sql/connect/php/download-drivers-php-sql-server?view=sql-server-ver16

Extract the downloaded file and copy the files that match your PHP version into the ext folder of your php folder

After that, you need to edit the php.ini (in your PHP folder) to add the drivers you just downloaded

extension=php_sqlsrv_82_ts_x64.dll
extension=php_pdo_sqlsrv_82_ts_x64.dll

Note that you have to edit the names of the extensions to match the driver files you just downloaded which match with PHP version, in my case it was 8.2 version

After saving the php.ini you must restart the apache server for changes to take effect

Now if you want to test the DB connection , you can open a terminal and go to tinker

php artisan tinker

and then type

DB::connection()->getDatabaseName()   

If you get the name of the DB, then the connection is good, but wait .. that doesn’t mean you are able to read or write from the DB. For example, if you tried to do a migrate and you get an error like this:

SQLSTATE[08001]: [Microsoft][ODBC Driver 17 for SQL Server]TCP Provider: The wait operation timed out.

 (Connection: sqlsrv, SQL: select * from sys.sysobjects where id = object_id(migrations) and xtype in (‘U’, ‘V’))

That means there is most probably a problem with the credentials or the port used

First, you need to make sure that the user has SQL Server authentication, not Windows authentication, you need to open SQL Server Management Studio and right on the Server from the left menu, click on Properties and then Security and choose SQL Server and Windows Authentication mode option

After clicking save, go to the left menu:  Security > Login and right click on the user name and click on Properties and make sure that the option of SQL Server Authentication is active

Better to restart the SQL Server by right click on the Server name from the left menu and click on Restart.

If you still get an error message, try to stop the SQL server Process from Task manager

How to abort with custom message in Laravel

If you want to abort with a custom message, you will find that in some code like this,

abort(400, 'custom error message');

the above code will show you the standard 400 error without any custom messages. You need to write the code like this

abort(
    response()->json(['message' => "My Custom error message"], 400)
  );

How to solve “Attempt to read property of Null”

Sometimes in Laravel, when you try to show a property of an object, for example :

{{ $user->name }}

you get an error like this :

Attempt to read property on null

which simply means that the object itself “user” is null and you can’t get a name property of Null. To solve this, you need to make sure that the user object is there first and then get the name but that will be a lot of coding and if statement, while there is a one-character solution to this, it is called a Nullsafe Operator and it is in PHP 8
the code will look like this

{{ $user?->name }}

you can use the same method in a chain of objects or even methods

$country = $session?->user?->getAddress()?->country;

There are other options that you can check in this article

Nothing to migrate in Laravel

If you are trying to migrate a single class you will do something like this

php artisan migrate --path = path_to_migration_file

if you get something like :

Nothing to migrate

and you are sure the file is there, then you can try to write the command like this

php artisan migrate --path="database/migrations/2022_11_04_1235_create_table.php"

Log Laravel

You can easily log your data in Larave, all you have to do is to use Log, and then log whatever you want, here is an example

<?php
 
namespace App\Http\Controllers;
 
use Log;
use App\User;
use App\Http\Controllers\Controller;
 
class UserController extends Controller
{
    /**
     * Show the profile for the given user.
     *
     * @param  int  $id
     * @return Response
     */
    public function showProfile($id)
    {
        Log::info('User ID: '.$id);
 
        return view('user.profile', ['user' => User::findOrFail($id)]);
    }
}

You can also use an array of contextual data

Log::info('User failed to login.', ['id' => $user->id]);

Laravel provides 8 levels of logging

Log::emergency($error);
Log::alert($error);
Log::critical($error);
Log::error($error);
Log::warning($error);
Log::notice($error);
Log::info($error);
Log::debug($error);

You can view the log file at: storage/laravel.log but you may find a huge file with thousands of line as this is the main file where all the logs are saved.

If you want to create your own log file, you will need to add a new channel in the config/logging.php

'channels' => [
        'myLog' => [
                    'driver' => 'single',
                    'path' => storage_path('logs/myLog.log'),
                    'level' => 'info',
                ],

where myLog.log is the file name you want to save your logs in

To write to your custom log file, you have to specify the channel you just created

Log::channel('myLog')->info('This is testing for my log file.');

ps. Don’t forget to empty the config cache for the updates to be active

from your terminal, you write: php artisan cache:clear

Finally, when you open myLog.log file, you will see something like this:

[2022-08-25 09:13:20] local.INFO: This is testing for my log file.

How to use withSum() with where condition

You can use withSum in query with where condition, here is an example:

If you want to list all Projects with the sum of all invoices that were issued this year:

$projects = Project::select('id', 'name', 'created_at')
            ->withSum(
                 ['invoices as prev_invoices' => function($query) {
                     $query->whereYear('invoices.issue_date', date('Y'));
                }], 'amount' 
             )
            ->get();

How to set a function in a model as an attribute

If you have a model with a function that you want to use it as an attribute, all you have to do is to use protected $appends in the Model class

For example, you have a Project class with a function that gets the sum of all invoices for that project

class Project extends Model
{
protected $appends = ['prev_invoices'];
....
public function getPrevInvoicesAttribute()       
    {
        $sum = Invoice::where('project_id', $this->id)
            
            ->sum('amount');
        return $sum;
    } 

Note that the function name must be formatted like that: “get” at the beginning, “Attribute” at the end, and the name to be CamelCase.

Laravel / PHP SOS

When your code is not working right and you have no idea what is wrong:

  • What is the language ?
    Yes, you heard me right, sometimes when you are writing javascript code inside a laravel/php page ..things could get mixed up
  • Remove the cache
    There are lots of cache types you need to clear depending on what you have changed, here are some commands to use:
    • php artisan config:cache
    • php artisan route:cache
    • php artisan view:cache
    • php artisan cache:clear
    • php artisan clear-compiled
    • composer dump-autoload
    • php artisan debugbar:clear
    • php artisan optimize
  • What is the type of the variables ?
    When you want to compare 2 variables and you are sure the result should be true, check the type of the variables, sometimes you could find that you are comparing a variable to an object or collection

How to view raw SQL of Laravel query?

There are a number of ways to view the raw SQL statement of your Larael query builder

->dd()

A simple way to show you the SQL statement along with its binding is replacing ->get(), first(), .. with ->dd(), here is an example:

$users = User::select('name')
                  ->where('id', '<', 20)
                  ->where('is_active', 1)
                  ->dd();

and the output will be like this:

"select `name` from `users` where `id` < ? and `is_active` = ?"
array:2 [▼
  0 => 20
  1 => 1
]
Continue reading “How to view raw SQL of Laravel query?”

How to add an external URL in Laravel balde

If you have a url that you want to get from DB and put it into Laravel blade and you want it to be linkable you may face a problem if the link doesn’t contain http:// as the browser will treat it as a page inside the current website.

For ex. if the link is external.com the html will be :

in Blade :

<a href = "{{ $site_url }}"> {{ $site_url }} </a>

in html:

<a href = "external.com">exterlnal.com</a>

The problem here is that when you click on that link , the browser will go to : www.mysite.com/exterlan.com

which will give you a 404.

You may think that to need to add http:// or https:// but all you need to add is just the // but then what if the url is saved with http:// or https:// then you better check for it first

<a href="@if(!str_contains( "$site_url", '//'))//@endif{{$site_url}}" target='_blank'>
                      {{ $site_url }}
                    </a>

ps. str_contains is a PHP8 function