Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A solution for globals vs. scope problem #1274

Closed
trustmaster opened this issue Nov 9, 2013 · 8 comments
Closed

A solution for globals vs. scope problem #1274

trustmaster opened this issue Nov 9, 2013 · 8 comments

Comments

@trustmaster
Copy link
Member

In Siena we've improved architecture by moving from single script flow to modules and requirements, but it introduced a side effect which many Siena developers come across from times to times. Suddenly you find that a variable is empty (e.g. table name in an SQL query) although it is declared as global. So you have to type global here and there to be sure that a correct value is retrieved.

It would be nice to avoid overusing global, keeping the code brief and backwards-compatible.

UPDATE

Below are example illustrating how this is implemented in Siena 0.9.15.

OK, the updated proposal in examples looks like this.

Example 1, declaring a table name:

// In page.functions.php:
cot::$db->registerTable('pages');

// In some 3-rd party module
function foo()
{
    global $db;
    $db->query("SELECT * FROM {$db->pages} WHERE page_count > 100");
    // ...
}

Example 2, several table names in one function:

function foo()
{
    global $db;
    $res = $db->query("SELECT p.*, t.*, s.*
        FROM {$db->forum_posts} AS p
            LEFT JOIN {$db->forum_topics} AS t ON t.ft_id = p.fp_topicid
            LEFT JOIN {$db->forum_sections} AS t ON s.fs_id = p.fp_sectionid
        WHERE fp_id = 123");
}

Example 3, using cot:: singleton to access Cotonti's key globals when not sure if inside function or global scope (e.g. in plugin/include file):

$limit = cot::$cfg['plugin']['myplug']['count'];
$caption = cot::$L['Count'];
cot::$sys['captioned_count'] = $caption . ': ' . $limit;

Example 4, registering an extrafield:

require_once cot_incfile('extrafields'):

cot_extrafields_register_table('pages');
@trustmaster
Copy link
Member Author

The most annoying is DB table names access. So how about using some registry variable like this:

// In page.functions.php:
$db->tab->pages = (isset($db_pages)) ? $db_pages : $db_x . 'pages';

// In some 3-rd party module
function foo()
{
    global $db;
    $db->query("SELECT * FROM {$db->tab->pages} WHERE page_count > 100");
    // ...
}

@esclkm
Copy link
Member

esclkm commented Nov 9, 2013

I think it is new line of code, But for me it is not needed
Aslo YOU write global $db. So 5 more symbols don't make any reason

@trustmaster
Copy link
Member Author

@esclkm compare this:

function foo()
{
    global $db, $db_forum_sections, $db_forum_topics, $db_forum_posts;
    $res = $db->query("SELECT p.*, t.*, s.*
        FROM $db_forum_posts AS p
            LEFT JOIN $db_forum_topics AS t ON t.ft_id = p.fp_topicid
            LEFT JOIN $db_forum_sections AS t ON s.fs_id = p.fp_sectionid
        WHERE fp_id = 123");
}

and this:

function foo()
{
    global $db;
    $res = $db->query("SELECT p.*, t.*, s.*
        FROM {$db->tab->forum_posts} AS p
            LEFT JOIN {$db->tab->forum_topics} AS t ON t.ft_id = p.fp_topicid
            LEFT JOIN {$db->tab->forum_sections} AS t ON s.fs_id = p.fp_sectionid
        WHERE fp_id = 123");
}

Still makes no sense?

@trustmaster
Copy link
Member Author

And also for include files. Currently you have to do something like this to avoid variable scope problems:

global $db_pages;
require_once cot_incfile('page', 'module');

global $db_forum_sections, $db_forum_topics, $db_forum_posts;
require_once cot_incfile('forums', 'module');

isn't it annoying?

@Dayver
Copy link
Member

Dayver commented Nov 9, 2013

I like it

@Kilandor
Copy link
Member

The issue can be a problem and inconvenient at time, for example a patch for an extension on upgrade has no access to $db_* vars and possibly others. Which can force you to either hardcode(bad) or use $GLOBALS while not really so bad, not so preferred. It could become possible also other vars such as $cfg, $sys, or others. The core will change the same, this just offers developers a way to access things always, in case for some reason its not avail. Preventing them from needing to modify the core

@trustmaster
Copy link
Member Author

OK, the updated proposal in examples looks like this.

Example 1, declaring a table name:

// In page.functions.php:
$db->pages = (isset($db_pages)) ? $db_pages : $db_x . 'pages';

// In some 3-rd party module
function foo()
{
    global $db;
    $db->query("SELECT * FROM {$db->pages} WHERE page_count > 100");
    // ...
}

Example 2, several table names in one function:

function foo()
{
    global $db;
    $res = $db->query("SELECT p.*, t.*, s.*
        FROM {$db->forum_posts} AS p
            LEFT JOIN {$db->forum_topics} AS t ON t.ft_id = p.fp_topicid
            LEFT JOIN {$db->forum_sections} AS t ON s.fs_id = p.fp_sectionid
        WHERE fp_id = 123");
}

Example 3, using cot:: singleton to access Cotonti's key globals when not sure if inside function or global scope (e.g. in plugin/include file):

$limit = cot::$cfg['plugin']['myplug']['count'];
$caption = cot::$L['Count'];
cot::$sys['captioned_count'] = $caption . ': ' . $limit;

@macik
Copy link
Member

macik commented Nov 10, 2013

It makes sense. Agree with this suggestion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants