A few functions for make work with PHP 7.4 (or more) projects easy and quickly.
    {
        'ta-tikoma/php.easy.nvim',
        config = true,
        keys = {
            {'-#', '<CMD>PHPEasyAttribute<CR>', ft = 'php'},
            {'-b', '<CMD>PHPEasyDocBlock<CR>', ft = 'php'},
            {'-r', '<CMD>PHPEasyReplica<CR>', ft = 'php'},
            {'-c', '<CMD>PHPEasyCopy<CR>', ft = 'php'},
            {'-d', '<CMD>PHPEasyDelete<CR>', ft = 'php'},
            {'-uu', '<CMD>PHPEasyRemoveUnusedUses<CR>', ft = 'php'},
            {'-e', '<CMD>PHPEasyExtends<CR>', ft = 'php'},
            {'-i', '<CMD>PHPEasyImplements<CR>', ft = 'php'},
            {'--i', '<CMD>PHPEasyInitInterface<CR>', ft = 'php'},
            {'--c', '<CMD>PHPEasyInitClass<CR>', ft = 'php'},
            {'--ac', '<CMD>PHPEasyInitAbstractClass<CR>', ft = 'php'},
            {'--t', '<CMD>PHPEasyInitTrait<CR>', ft = 'php'},
            {'--e', '<CMD>PHPEasyInitEnum<CR>', ft = 'php'},
            {'-c', '<CMD>PHPEasyAppendConstant<CR>', ft = 'php', mode = {'n', 'v'}},
            {'-p', '<CMD>PHPEasyAppendProperty<CR>', ft = 'php', mode = {'n', 'v'}},
            {'-m', '<CMD>PHPEasyAppendMethod<CR>', ft = 'php', mode = {'n', 'v'}},
            {'__', '<CMD>PHPEasyAppendConstruct<CR>', ft = 'php'},
            {'_i', '<CMD>PHPEasyAppendInvoke<CR>', ft = 'php'},
            {'-a', '<CMD>PHPEasyAppendArgument<CR>', ft = 'php'},
        }
    },
    {
        'ta-tikoma/php.easy.nvim',
        dependencies = {
            'L3MON4D3/LuaSnip',
        },
        opts = {
            onAppend = {
                engine = 'LuaSnip'
            }
        },
        keys = {
            ...
        }
    },
| Example Key Binding | Function | Description | 
|---|---|---|
| Any | function or property or constant | |
| -y | PHPEasyCopy | Yank (copy) any under cursor | 
| -r | PHPEasyReplica | Replica any: Copy under cursor, paste after current and trigger rename function | 
| -d | PHPEasyDelete | Delete any under cursor | 
| -b | PHPEasyDocBlock | PhpDocBlock for any or class or variable | 
| -# | PHPEasyAttribute | Add #[Attribute] for any or class | 
| Append | ||
| -c | PHPEasyAppendConstant | Append constant | 
| -p | PHPEasyAppendProperty | Append property | 
| -m | PHPEasyAppendMethod | Append method | 
| -t | PHPEasyAppendTrait | Append tait | 
| -__ | PHPEasyAppendConstruct | Append **__**construct | 
| -_i | PHPEasyAppendInvoke | Append __invoke | 
| -a | PHPEasyAppendArgument | Append new argument in current function | 
| Objects | ||
| -uu | PHPEasyRemoveUnusedUses | Remove unused uses from current file, if you use lsp: intelephense | 
| -e | PHPEasyExtends | Extends current class | 
| -i | PHPEasyImplements | Implements current class | 
| --c | PHPEasyInitClass | Initialize class in current file | 
| --ac | PHPEasyInitAbstractClass | Initialize abstract class in current file | 
| --i | PHPEasyInitInterface | Initialize interface in current file | 
| --t | PHPEasyInitTrait | Initialize trait in current file | 
| --e | PHPEasyInitEnum | Initialize enum in current file | 
{
    regex = { -- regex for parse php file
        tab = '    ',
        startTab = '^' .. tab,
        visibility = startTab .. '\\(public\\|protected\\|private\\|\\)\\s\\{1}',
        static = '\\(static\\s\\|\\)',
        readonly = '\\(readonly\\s\\|\\)',
        constant = visibility .. 'const ',
        property = visibility .. static .. readonly .. '\\(?*\\w\\+\\s\\|\\)\\$',
        method = visibility .. static .. 'function',
        construct = method .. ' __construct(',
        methodEnd = startTab .. '}',
        comment = startTab .. '\\/',
        commentMiddle = startTab .. '\\*',
        commentEnd = startTab .. '\\s\\*',
        any = startTab .. '[p}]\\{1}',
        variable = '\\(' .. tab .. '\\)\\+\\$\\w\\+\\s\\{1}=\\s\\{1}',
        object = '^\\(final class\\|abstract class\\|class\\|interface\\|trait\\|enum\\)\\s\\{1}',
    },
    onSave = { -- on save php file action
        removeUnusedUses = true -- remove unused uses (then use lsp: intelephense)
    },
    onAppend = { -- on append entity
        engine = 'defalut' -- how to insert template. 'default' - just string, 'LuaSinp' - via 'L3MON4D3/LuaSnip'
    }
}
Example configuration
    {
        'quolpr/quicktest.nvim',
        config = function()
            local qt = require("quicktest")
            local root_patterns = { ".git" }
            local root_dir = vim.fs.dirname(vim.fs.find(root_patterns, { upward = true })[1])
            qt.setup({
                adapters = {
                    require("php-easy-nvim.quicktest.adapters.phpunit")({
                        command = root_dir .. "vendor/bin/phpunit",
                    })
                },
                use_baleia = false
            })
        end,
        dependencies = {
            "nvim-lua/plenary.nvim",
            "MunifTanjim/nui.nvim",
        },
        keys = {
            ...
        }
    }
If you use docker. Add file phpunit.sh to root directory of project:
#!/bin/bash
docker exec -i php vendor/bin/phpunit ${@}
When chmod +x phpunit.sh.
Change configuration:
    {
        'quolpr/quicktest.nvim',
        config = function()
            local qt = require("quicktest")
            local root_patterns = { ".git", "phpunit.sh" }
            local root_dir = vim.fs.dirname(vim.fs.find(root_patterns, { upward = true })[1])
            qt.setup({
                adapters = {
                    require("php-easy-nvim.quicktest.adapters.phpunit")({
                        command = root_dir .. "phpunit.sh",
                    })
                },
                use_baleia = false
            })
        end,
        dependencies = {
            "nvim-lua/plenary.nvim",
            "MunifTanjim/nui.nvim",
        },
        keys = {
            ...
        }
    }
--t
--i
--ac
--c
-b



