Fellipe Sanches' website

Category: Uncategorized

  • The easiest way to install xdebug with Ubuntu

    Here’s a clean, American-blog-style rewrite:

    Setting up Xdebug isn’t always straightforward. Depending on your setup, you might need to wire it into your IDE or get it running inside a Docker container.

    So in this tutorial, we’ll walk through a simple, foolproof way to set up Xdebug on Ubuntu Linux.

    Instalation

    First of all, check your PHP version with php -v.

    php -v
    PHP 8.4.15 (cli) (built: Nov 20 2025 17:43:25) (NTS)
    Copyright (c) The PHP Group
    Built by Debian
    Zend Engine v4.4.15, Copyright (c) Zend Technologies
        with Zend OPcache v8.4.15, Copyright (c), by Zend Technologies
        with Xdebug v3.4.7, Copyright (c) 2002-2025, by Derick Rethans

    Ondřej Surý’s PPA

    Now, if you installed PHP from Ondřej Surý’s repository, which is always the most up-to-date, you can install xdebug with.

    Note that you need to change your xdebug version to match your PHP version.

    sudo apt-get install php8.4-xdebug

    Default PPA

    But, if you are using the standard version of PHP included with Ubuntu, which is usually outdated, simply run:

    sudo apt-get install php-xdebug

    Run the php -v again and you should see the Xdebug information on the last line:

    php -v
    PHP 8.4.15 (cli) (built: Nov 20 2025 17:43:25) (NTS)
    Copyright (c) The PHP Group
    Built by Debian
    Zend Engine v4.4.15, Copyright (c) Zend Technologies
        with Zend OPcache v8.4.15, Copyright (c), by Zend Technologies
        with Xdebug v3.4.7, Copyright (c) 2002-2025, by Derick Rethans

    Then, run the built-in web server and you will also see a warning:

    php -S 127.0.0.1:8000
    [Sat Nov 22 12:00:22 2025] PHP Warning:  JIT is incompatible with third party extensions that override zend_execute_ex(). JIT disabled. in Unknown on line 0
    [Sat Nov 22 12:00:22 2025] PHP 8.4.15 Development Server (http://127.0.0.1:8000) started

    This warning is normal when you’re using Xdebug on PHP 8.1+ (including 8.4).
    Nothing is broken… So, what this warning means?

    Xdebug overrides the internal zend_execute_ex()function, which the PHP Just-In-Time compiler (JIT) also needs, since both can’t run at the same time, PHP automatically disables JIT.

    This scenario, with no JIT and using Xdebug, is generally satisfactory for a development environment.

    Usage

    Step Debugging

    Xdebug’s step debugger allows you to interactively walk through your code to debug control flow and examine data structures.

    Configuring Step Debugging

    On the linux shell, run the command below to find the current php.ini file.

    php -i | grep "Loaded Configuration File"

    Output: Loaded Configuration File => /etc/php/8.4/cli/php.ini

    Then, change (or include) the setting to xdebug.mode=debug, in case of inclusion, you can put it at the bottom of the file.

    In setups where PHP/Xdebug and your IDE all run on the same host, this is all you need to configure on the PHP and Xdebug side. 

    Command Line Debug Client

    The command line debug client allows you to debug PHP scripts without having to set up an IDE. This might be useful if you don’t want to tie your xdebug to a specific IDE.

    A binary for Linux, macOS, and Windows is available on the Xdebug downloads page. Here I will use Linux (x86_64).

    In the project root folder:

    wget https://xdebug.org/files/binaries/dbgpClient
    chmod +x dbgpClient
    ./dbgpClient 
    #OUTPUT
    Xdebug Simple DBGp client (0.6.1)
    Copyright 2019-2024 by Derick Rethans
    
    Waiting for debug server to connect on port 9003.

    So if you haven’t already, start the built-in PHP server in a new command prompt:

    php -S 127.0.0.1:8000

    The Xdebug output will change to:

    #OUTPUT
    Connect from 127.0.0.1:37386
    DBGp/1.0: Xdebug 3.4.7  For PHP 8.4.15
    Debugging file:///home/fellipe/projects/symfony/my-clone-of-symfony-gs/index.php (ID: 294841/YOUR-NAME)
    (cmd)  

    If PHP/Xdebug run on a different machine, virtual host, or in a Docker container, you need to tell Xdebug where to make the debugging connection to.

    Configuriing Xdebug to connect with a PHPStorm

    ./dbgpClient
    Xdebug Simple DBGp client (0.6.1)
    Copyright 2019-2024 by Derick Rethans

    Waiting for debug server to connect on port 9003.

  • How to copy files between WSL Ubuntu instances

    It’s not always possible to update your Ubuntu version with just one command. In these cases, we need to set up a new server and migrate the files between them.

    In this tutorial we will see how to copy your projects from Ubuntu 20.04 to Ubuntu 24.04 under WSL.

    Listing your current WSL distros

    PowerShell
    wsl -l -v

    You will see something like this:

    PowerShell
    Ubuntu-20.04    Running   2

    Create the new Ubuntu distro

    In the Windows Command Prompt ou Powershell run the command below, and you will create a new Ubuntu WSL instance, without replace the current.

    PowerShell
    wsl --update
    wsl --install -d Ubuntu-24.04

    List the current WSL distros again with wsl -l -v , you should see both the newest instance now.

    PowerShell
    Ubuntu-20.04    Running   2
    Ubuntu-24.04    Stopped   2

    Copy files between instances

    Someone could copy the files between the WSL instances using a Windows command like robocopy, but this method would be extremely slow.

    Others might try copying the files from within the Linux instances, which could be more work than expected.

    Instead, we will copy the files directly inside the Windows Explorer, the simpliest way.

    In Windows Explorer, find the folder of both WSL, and just copy the files that you need from origin folder to destiny folder:

    Easy, no? But…

    The copies will be made. However, in the destination directory, we will have the Zone.Identifier files included; It is an NTFS Alternate Data Stream (ADS) automatically created by Windows.

    We don’t need them on our Linux system, so let’s remove them. Enter in the newest Linux created typint this in cmd or PowerShell:

    PowerShell
    wsl -d Ubuntu-24.04

    Go to the project directory:

    Bash
    cd ~/projects/
    sudo find . -type f -name '*:Zone.Identifier' -exec rm -f {} \;

    Okay, now we only have the same files from the old Ubuntu in the new Ubuntu.

    Finally, we now just need to adjust the permissions that are set for the root user to work on the files contained in /home/fellipe/projects which currently are granted to the root user. For it type:

    Bash
    sudo chown -R fellipe:fellipe /home/fellipe/projects

    Okay…

    Now you have your files on a new server, ready to be worked on.

    Remember, since you’re working from a new Ubuntu, the entire work environment will also need to be configured; things like the web server and PHP will need to be installed.

  • XDebug alternatives for debugging PHP

    Sometimes xdebug can be tricky to install and configure, especially in scenarios where it wasn’t designed to work natively, such as running your project in WSL or Docker.

    Today I will show you two simpler alternatives for debugging PHP, which will help you debug your project without wasting time on long installations.

    Pre-installation

    What we will use in this tutorial:

    • PHP 8.4
    • Composer 2.8

    Note: Since all versions of PHP 7 and Composer 1 are no longer supported, avoid using them.

    You can find a tutorial on how to update your PHP 7 to PHP 8 here, and a tutorial on how to install composer the right way here.

    To update your composer, you can simply run:

    ./composer self-update

    Kint – Advanced PHP dumper

    🐈‍⬛ https://github.com/kint-php/kint

    The first debug tool is the Kint. Think of Kint as a smart evolution of a var_dump(), but much more complete and interactive.

    Instalation

    ./composer require kint-php/kint --dev

    Usage with Composer

    <?php
    
    include 'vendor/autoload.php';
    
    d('Dumped with Kint');
    
    $time = new DateTime();
    $data = [
        'id' => 42,
        'status' => 'active',
        'features' => ['debug', 'logging', 'profiling'],
        'settings' => [
            'theme' => 'dark',
            'notifications' => true
        ]
    ];
    $object = new stdClass();
    $object->title = "My Symfony Clone";
    $object->author = "Fellipe";
    $object->version = 1.0;
    
    d($time, $data, $object);

    Resources

    • Live search – This feature let you to fint values through complex data with ease.
    • Dump Data – you can unfold and explore instantly arrays, jsons, php objects, etc.
    • Generates code – Kint generates the exact code you need to access specific fields.

    Kind have a lot of other nice features, you can see all them here: https://kint-php.github.io/kint/

    PHP Debug Bar

    🐈‍⬛ https://github.com/php-debugbar/php-debugbar

    The next tool is the PHP Debug Bar, that displays a debug bar in the browser with information from PHP.

    Installation

    ./composer require --dev php-debugbar/php-debugbar

    Usage with Composer

    <?php
    
    require 'vendor/autoload.php';
    use DebugBar\StandardDebugBar;
    
    $time = new DateTime();
    $data = [
            'id' => 42,
            'status' => 'active',
            'features' => ['debug', 'logging', 'profiling'],
            'settings' => [
                    'theme' => 'dark',
                    'notifications' => true
            ]
    ];
    
    $dataJson = json_encode($data);
    
    $object = new stdClass();
    $object->title = "My Symfony Clone";
    $object->author = "Fellipe";
    $object->version = 1.0;
    
    $debugbar = new StandardDebugBar();
    $debugbarRenderer = $debugbar->getJavascriptRenderer();
    
    // --- MESSAGES ---
    $debugbar["messages"]->addMessage("Hello world in debugbar!");
    $debugbar["messages"]->addMessage("Current time: " . $time->format("Y-m-d H:i:s"));
    $debugbar["messages"]->addMessage($data);
    $debugbar["messages"]->addMessage("JSON data: " . $dataJson);
    $debugbar["messages"]->addMessage($object);
    $debugbar["time"]->addMeasure("Script started", 0, microtime(true));
    
    ?>
    <html>
    <head>
        <?php echo $debugbarRenderer->renderHead(); ?>
    </head>
    <body>
    
    <h1>DebugBar Test</h1>
    
    <?php echo $debugbarRenderer->render(); ?>
    
    </body>
    </html>
    

    Resources

    • Search – This feature let you to fint values through complex data with ease.
    • Dump Data – you can unfold and explore instantly arrays, jsons, php objects, etc.

    PHP Debug Bar have a lot of other nice features, you can see all them here: https://php-debugbar.com/

    Conclusion

    Both are useful tools for debugging. While Kint generates the appropriate code to access data, the PHP Debug Bar seems to make debugging easier with its toolbar.

    Keep in mind that both have more advanced features that weren’t covered here.
    So, which one do you prefer? Try them out and decide for yourself!

  • All terms of Object-oriented programming (OOP)

    Four Pillars of Object-oriented programming

    A trick a trick I invented to memorize the 4 pillars of OOP:

    P Polymorphism
    I Inheritance
    L
    L
    A Abstraction
    R

    Where is the E for Encapsulation? It was encapsulated! (just kidding).

    Design Principles

    D Decomposition
    E Encapsulation
    S
    I
    G Generalization
    N

    Where is the A for Abstraction? It was omitted due to a poor abstraction.

  • Dicas para montar um layout que não quebra #1

    Neste artigo vou apresentar 10 dicas de construção para layouts que eu como desenvolvedor back-end gostaria de ter aprendido logo quando comecei a me aventurar no front-end!

    Porém, vou deixar tudo aqui, resgistrado para você não sofrer com o que eu sofri.

    Dicas para a construção de um layout web que não quebra:

    Algura e largura com vh e vw

    Para acomodar blocos de layout de forma que ocupem a totalidade da página, ao invés de %, use as unidades de medida vh (viewport height) e vw (viewport width).

    Um elemento HTML <div> com width de 25vw, vai ocupar 25% da largura da área disponível no navegador.

    A questão com a unidade % é que ela é relativa, e ajusta as dimenões dos elementos filhos com base em seu elemento pai, o que nos obriga muitas vezes a ter de definir um tamanho explicito ao elemento pai.

    Já trabalhar com vw e vh vai ajustar sempre seus itens de layout com base no tamanho do viewport, bastante você calcular quando da altura e largura disponíveis na tela do navegador quer dar aos seus objetos, sem se preocupar com hierarquias para isso.

    Largura de colunas com ch

    Eu simplesmente adoro usar a unidade ch (character unit) para definir a largura das colunas de uma tabela, especialmente as colunas estreitas e de tamanho máximo previsível, como as de id numérico.

    Então suponhamos que você sabe que sua tabela vai retornar no máximo 4 dígitos de registros (1 – 9999), você pode usar 4ch na coluna id, para delimitar a largura desta coluna exatamente a quatro caracteres.

    Ou melhor ainda, você pode ajustar com js o css width desta coluna para a largura do maior registro retornado. Ou seja, se seu maior registro retorna do foi o id 57 que tem dois digitos, defina dinamicamente 2ch, se for 500 que tem três dígitos defina 3ch, e assim por diante.

    Já no caso de colunas mais largas, como as de nome e endereço, as quais faria menos sentido prever um tamanho de largura ideal, você pode dividir a porcentagem de 100% entre elas. Ou seja, divida 100% de largura entre todas as outras colunas que não usem ch.

    A melhor forma de sobrescrever estilos css

    Muitas vezes precisamos sobrescrever estilos CSS. A melhor forma de fazer isso é inserir um arquivo de estilos como custom.css após a chamada do arquivo principal de CSS.

    Porém se você não puder fazer essa chamada no local correto, que seria dentro da seção <head>, prefira então usar ccs inline direto no HTML.

    De forma alguma abra tags <style> no <body>, isso funciona mas é incorreto, por isso não há garantias de que os navegadores vão tolerar isso em futuras versões, além de é claro deixar o código estrutural feio e confuso.

    Por fim, você também pode usar JS para alterar o estilo desejado. Só recomendo sempre, evitar misturar todas as técnicas disponíveis, procure escolher um padrão.

    Como organizar seu arquivo CSS

    Não é raro começar a adicionar código ao seu arquivo CSS e de repente se perder em sua organização. Por isso abaixo deixa uma ordem para manter as coisas:

    • Reset ou normalize (margin, padding, etc)
    • Variáveis / root
    • Layout geral (header, footer, main)
    • Componentes reutilizáveis (menus, botões, cards, formulários)
    • Helpers/utilitários (classes prontas para diversos usos)
    • Media queries (repita tudo o que fez para a versão desktop, para o mobile)

  • w2ui Themes


    The basic approach to using themes in w2ui is to include w2ui.css and then include some kind of w2ui-custom.css, where you can override the default styles based on your needs.

    This straightforward approach is the one recommended by the creator of w2ui.

    This shows us that sometimes insisting on complex solutions as the “right” ones is purely a matter of preference, not necessarily a fact.

    Let’s keep it simple!

  • Restringir menus para usuários do WordPress

    No WordPress pode ser útil restringir quais menus um usuário pode ter acesso. Não é difícil encontrarmos uma situação onde um usuário de um site deve ter acesso aos plugins WooCommerce, para gerenciar suas vendas e Easy Appoinments para gerenciar os agendamentos de seus clientes, mas não pode ter acesso aos menus Tools ou Settings, por exemplo.

    A questão é que o WordPress por padrão não faz esse tipo de gerenciamento de permissões, e assim sendo, nós temos duas formas de resolver isso, a primeira é usando algum plugin de terceiros, a segunda é criando nosso próprio plugin para gerenciar as permissões.

    Neste tutorial vamos desenvolver a segunda opção, eu a considero mais estável e segura, levando em conta que você terá total controle e conhecimento do que foi feito e do que está rodando no seu site.

    Mãos a massa!

    Antes de começarmos de fato, um alerta! É comum encontrar na internet instruções para pôr código personalizado no arquivo functions.php do seu tema ativo, porém isso é um equívoco, uma vez que o arquivo functions.php pode ser sobrescrito em uma atualização do seu tema, apagando assim qualquer código personalizado inserido nele.

    Mais uma vez então concluímos que uma melhor solução para inserir código personalizado em um site WordPress é criar seu próprio plugin, vamos fazer isso a seguir. E o melhor, é que isso é fácil de fazer!

    Dentro da pasta de plugins crie um diretório e um arquivo com o mesmo nome menu-filter/menu-filter.php

    Este diretório e arquivos não precisam ter o mesmo nome, porém para um plugin muito simples com somente um arquivo, como é neste caso, isso deixa as coisas mais claras.

    Adicione o código abaixo ao arquivo:

    <?php
    /**
     * Plugin Name: My Website Admin Menu Filter
     * Description: Show only Appointments, WooCommerce e Products menus
     * Version: 1.0
     * Author: Fellipe Sanches
     */
    
    function ocultar_menus_para_secovi_colaborador() {
      if (!is_user_logged_in()) return;
    
        $user = wp_get_current_user();
        $email = $user->user_email;
    
        $admins = array(
            "email1@provider.com", 
            "email2@provider.com"
            );
    
        if (!in_array($email, $admins, true)) {
           remove_menu_page('index.php');
           remove_menu_page('edit.php'); // Posts
           remove_menu_page('upload.php'); // Media
           remove_menu_page('link-manager.php'); // Links
           remove_menu_page('edit-comments.php'); // Comenetários
           remove_menu_page('edit.php?post_type=page'); // Pages
           remove_menu_page('plugins.php'); // Plugins
           remove_menu_page('themes.php'); // Appearance
           remove_menu_page('users.php'); // Users
           remove_menu_page('tools.php'); // Tools
           remove_menu_page('edit.php?post_type=project'); //Projetos
           remove_menu_page('options-general.php'); // Settings
           remove_menu_page('et_divi_options'); // Divi
        }
    }
    
    function ocultar_menu_novo_para_secovi_colaborador() {
      if (!is_user_logged_in()) return;
    
        $user = wp_get_current_user();
        $email = $user->user_email;
    
        if (!in_array($email, $admins, true)) {
            global $wp_admin_bar;
            $wp_admin_bar->remove_node( 'new-content' );
            $wp_admin_bar->remove_node( 'comments' );
            $wp_admin_bar->remove_node( 'woocommerce-site-visibility-badge' );
            $wp_admin_bar->remove_node( 'updates' );
            
        }
    }
    
    add_action( 'wp_before_admin_bar_render', 'ocultar_menu_novo_para_secovi_colaborador' );
    add_action( 'admin_init', 'ocultar_menus_para_secovi_colaborador' );
    

    O plugin irá aparecer no seu menu de plugins:

  • PHP: três décadas impulsionando a web

    Em 8 de Junho de 2025, o PHP (Hypertext Preprocessor) completa 30 anos de existência, consolidando-se como uma das linguagens de programação mais influentes e duradouras da história.

    O PHP me proporcionou o primeiro cliente de desenvolvimento web ainda em 2010, uma imobiliária na cidade Maricá – RJ. Na época, como era constume, eu desenvolvi o projeto com ajuda de um livro do tipo que te guia a fazer um projeto completo, chamado “Faça um Site Orientado por Projeto Php 5. 2 Com Mysql 5. 0 – Carlos A. J. Oliviero”. Boas lembranças!

    Criado em 1995 por Rasmus Lerdorf, o PHP nasceu como um conjunto de scripts em C para suprir suas necessidades pessoais de programação. O que começou como uma ferramenta pessoal rapidamente evoluiu para uma linguagem de código aberto, usada por milhões de desenvolvedores ao redor do mundo.

    Durante esses últimos 30 anos o PHP passou por diversas melhorias, até avanços modernos como os do PHP 8.x, com suporte a tipagem estática, compilação JIT e recursos orientados a objetos mais sofisticados, a linguagem acompanhou — e em muitos casos, antecipou — as demandas da web moderna!

    Plataformas como WordPress (incluindo WooCommerce), Drupal, Joomla e Magento têm PHP como base até hoje, o PHP também conta com frameworks modernos e robustos como o Laravel e o Symfony, e isso tudo faz com que nada menos que 3/4 dos sites na internet atualmente utilizem PHP como linguagem de server-side, segundo estatísticas da W3Techs.

    Sem dúvida a longevidade do PHP é graças a sua comunidade fiel e ativa, sua documentação completa e organizada, e sua facilidade de aprendizado, o que fez dela a porta de entrada para milhares de desenvolvedores iniciantes.

    Com 30 anos de história, o PHP continua evoluindo, provando que sair na frente e manter uma base sólida, é o segredo para se manter na liderança. Parabéns ao PHP e a todos que contribuíram para sua jornada até aqui!

    <?php
    
    // Define emojis usando unicode
    $coracao = "\u{2764}\u{FE0F}";
    $cone = "\u{1F389}";
    
    echo "Parabéns pelos 30 anos proporcionados por\n todos que " . $coracao . " e usam o PHP! " . $cone\n;

    Resultado:

    Parabéns pelos 30 anos proporcionados por
    todos que ❤️ e usam o PHP! 🎉
  • How update from PHP 7.x to PHP 8.x at Ubuntu Linux

    Apt compatibility

    Another point to consider is that often an older PHP version, such as 7.4, is running on an older Ubuntu Linux distribution like 20.04. In this case, updates via apt to newer packages like those for PHP 8 will also be problematic. If possible, first update your Linux distribution to the latest LTS version.

    Code compatibility

    Upgrading from any version of PHP 7 to any version of PHP 8 is a major version jump and there is no single “self-update” command or “auto-update” button to do this, furthermore PHP 8 introduces breaking changes that could stop your old code from working, so we need be careful with this update.

    However, assuming all the risks of the code, we will perform the update using the apt package manager. Below let’s see the process to upgrade your system.

    The “Ondřej Surý” PPA

    Standard Ubuntu repositories usually lack the newest PHP versions, so you need use the standard third-party repository maintained by Ondřej Surý (a Debian PHP maintainer). To do it, type in shell:

    sudo apt update
    sudo apt install -y software-properties-common
    sudo add-apt-repository ppa:ondrej/php
    sudo apt update

    Get he extensions you had for PHP 7.x

    dpkg -l | grep php7 | cut -d ' ' -f 3
    Output:
    
    $ dpkg -l | grep php7 | cut -d ' ' -f 3
    php7.4-cli
    php7.4-common
    php7.4-mbstring
    php7.4-opcache
    php7.4-readline
    php7.4-xml

    Install PHP 8.x

    In a text editor, you can paste the output of the grep, and create your install command replacing what you need, like this:

    sudo apt install -y php8.4 php8.4-cli php8.4-common php8.4-mbstring php8.4-opcache php8.4-readline php8.4-xml

    Okay, now you have PHP 8 configured with the same packages as PHP 7.

  • Observer

    Auction and bidder, or news broadcast and viewer. These are examples of the observer design pattern. In each of these, relationships are generally one subject to many observers. One auction is observed by many bidders. One broadcast is observed by many viewers.

    As a behavioral pattern, it makes it easy to distribute and handle notifications of changes across systems, in a manageable and controlled way. 

    There are many different ways and situations you can apply the observer design pattern.