Cant create table on plugin activation

I am trying to create table on plugin activation, I tried making the same function inside the class and calling it from the constructor, and I tried calling it outside the class and finally i tried to make another php file for calling it using the register_activation_hook, but nothing worked

plugin-code:

<?php
/**
*@package pageauthors
**/

/** 
* Plugin Name: Page Authors
* Plugin URI: https://www.localhost.com/plugin
* Description: Allows you to add multiple authors to your wordpress post.
* Version: 1.0.0 
* Author: Raphael Eid.
* Author URI: https://www.localhost.com/
* License: GPL v2 or Later 
* Text Domain: PageAuthors
*/

$db = mysqli_connect('localhost','x','x','x');
//We can use require_once('../../../wp-config.php');
//mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);

defined('ABSPATH') or die('Error my friend');

class pageauthors{

    function register(){
        //Call the Scripts
        add_action('admin_enqueue_scripts', array($this, 'enqueue'));

        //Create in the admin function
        add_action('admin_menu', array($this, 'add_admin_pages'));
    }   
    
    public function add_admin_pages(){
        //add_menu_page( string $page_title, string $menu_title, string $capability, string $menu_slug, callable $function = '', string $icon_url = '', int $position = null )
        add_menu_page('Add Author', 'Add Author', 'manage_options', 'raphaelprefix_plugin', array($this, 'admin_index'), 'dashicons-insert', 110);
    }

    public function admin_index(){
        define( 'MY_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
        include( MY_PLUGIN_PATH . 'templates/index.php');
        // include( MY_PLUGIN_PATH . 'index.php');
        include( MY_PLUGIN_PATH . 'templates/showAuthors.php');
        // require_once plugin_dir_path(__FILE__) . 'templates/index.php';
    }    

    function deactivate(){
        global $wpdb;
        $table_name = $wpdb->prefix . 'postsauthors';
        $sql = "DROP TABLE IF EXISTS $table_name";
        $wpdb->query($sql);
        delete_option("my_plugin_db_version");
    }

    function enqueue(){
        //Here we can enqueue and we should create the assets (css and js)
        wp_enqueue_style('mypluginstyle', plugins_url('/assets/mystyle.css', __FILE__) );
        wp_enqueue_script('mypluginstyle', plugins_url('/assets/mystyle.js', __FILE__) );
    }

}

if(class_exists('pageauthors')){
    $raphplugin = new pageauthors();
    $raphplugin->register();
    // $raphplugin->activate();
    $raphplugin->deactivate();

}

function installer(){
    include('installer.php');
}

//Activate - Register Activation Hook(__FILE__, array($instance, function))
register_activation_hook(__FILE__, 'installer');

//Deactivate - Register Deactivation Hook(__FILE__, array($instance, function))
register_deactivation_hook(__FILE__, array($raphplugin, 'deactivate') );

?>

installer.php

<?php
$db = mysqli_connect('localhost','x','x','x');
    global $wpdb;
    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');

    if (count($wpdb->get_var('SHOW TABLES LIKE "wp_postsauthors"')) == 0){

        $sql = "CREATE TABLE `wp_postsauthors` 
        ( `ID` INT(200) NOT NULL AUTO_INCREMENT , `post_ID` INT(200) NOT NULL , 
        `author_name` VARCHAR(200) NOT NULL , `title` VARCHAR(200) NOT NULL , 
        `description` VARCHAR(200) NOT NULL , PRIMARY KEY (`ID`)) ENGINE = InnoDB;";

dbDelta($sql);

}

Nothing is working even tho I am typing everything correctly

Answer

I’m going to simplify things as much as possible. Activation hooks are always frustrating to debug because of their async-like behavior.

First, you actually don’t need to if check on whether the table exists, that’s what dbDelta does for you already. You can actually change your schema that’s defined in $sql later and dbDelta will attempt to figure that out and handle things automatically for you, too. In the real world, however, I have found that semi-complex table logic doesn’t always make it through to an ALTER TABLE. Instead, most people keep track of their schema version and run table upgrades on plugin update. But that’s for later.

Second, never assume the WordPress table prefix, that is asking for trouble some day. Instead, always use $wpdb->prefix.

The code below is the smallest version of a plugin that does what you are looking for. Instead of a function in a file, I’m just using a local anonymous function. The bulk of the code is the same as yours, just with some formatting that my IDE does for me automatically. This code is a full plugin which I’d recommend testing first. Once you’ve confirmed it is working, you should be able to pull the activation logic out. It is not wrong to use another file, I just try to remove as much distraction when I debug things.

<?php

/**
 * Plugin Name: Page Authors
 */

register_activation_hook(
    __FILE__,
    static function () {
        global $wpdb;
        require_once ABSPATH . 'wp-admin/includes/upgrade.php';

        // Never assume the prefix
        $table_name = $wpdb->prefix . 'postsauthors';

        $sql = "CREATE TABLE `${table_name}` 
                (
                    `ID` INT(200) NOT NULL AUTO_INCREMENT ,
                    `post_ID` INT(200) NOT NULL ,
                    `author_name` VARCHAR(200) NOT NULL ,
                    `title` VARCHAR(200) NOT NULL ,
                    `description` VARCHAR(200) NOT NULL ,
                    PRIMARY KEY (`ID`)) ENGINE = InnoDB;";

        dbDelta($sql);
    }
);