Page 2 of 4

Posted: Wed Sep 20, 2006 10:29 am
by RobertGonzalez
Hockey, were you drinking when you posted that? 8O

Posted: Wed Sep 20, 2006 10:56 am
by n00b Saibot
Everah wrote:Hockey, were you drinking when you posted that? 8O
is that Hockey, i thought that was cockey :lol:

Posted: Wed Sep 20, 2006 11:08 am
by Maugrim_The_Reaper
Can't think of any reason to use constants a lot. Usually I setup constants for strictly unchangeable values, status codes, etc. Config data I keep in an immutable Settings object. Most other things are data which may change at some point - the possibility of change pushes towards a config value rather than a constant. PI is a classic example, there's lots of other fixed numbers out there not covered explicitly by PHP constants...

Posted: Wed Sep 20, 2006 6:52 pm
by Ambush Commander
I have sworn off constants. Haven't used a single one for... what has it been, a year and a half? There's nothing you can't stash away in a Singleton. Plus, constants are dead slooowww... (I remember attempting to profile an application and being dismayed that the define and defined calls in ADOdb chewing up most of the execution time).

Posted: Thu Sep 21, 2006 12:55 am
by matthijs
So there seems to be a majority of people who don't like/use constants a lot. Application settings should go in an object. But - and please correct me if I'm wrong - that object needs to get it's data from somewhere, isn't it? So all the settings go in a database table? Is that a commonly used practice? And with one object ( a registry?) one gets all the config/settings data from the db? (ok, or another form of data storage like an xml file)

Posted: Thu Sep 21, 2006 3:47 am
by Maugrim_The_Reaper
Usually a Config/Settings object will import from a separate source (XML, YAML, INI, PHP variable/array list, DB). Once the values are loaded up the object will remain immutable - no setters, just getters simply put. Personally I break that sometimes and let the data be manipulated. I doubt that's particularly safe though since any change could impact a later piece of application logic relying on the changed setting value. Config data is presumably fixed until the source data is modified directly.

The way I usually structure it is to use a Config object family (simple Parent->Children (format specific) hierarchy) to import specific types of config formats into an immutable object. This object is then registered to a Registry. The Registry itself has no direct access to the values - it just stores the dedicated Config object for later retrieval.

Posted: Thu Sep 21, 2006 10:50 am
by matthijs
Ok thanks Maugrim, I'll imprint your advice in my memory

Posted: Thu Sep 21, 2006 11:18 am
by alex.barylski
matthijs wrote:So there seems to be a majority of people who don't like/use constants a lot. Application settings should go in an object. But - and please correct me if I'm wrong - that object needs to get it's data from somewhere, isn't it? So all the settings go in a database table? Is that a commonly used practice? And with one object ( a registry?) one gets all the config/settings data from the db? (ok, or another form of data storage like an xml file)
Just an opinion but...

Application settings in a DB have the following disadvantages:

1) Application wide so only one table is needed but only a single record as well. This kind of wastes that table for future expansion. Tables are for storing record(s) of information - thats plural not singular. Thats would be like storing linear records in an XML file. Technically allowed, but conceptually display naievity (sp?).

2) SQL is secure, but likely overkill for general application settings. If your DB passwords are changed or DB server goes down, your application cannot initialize, so in this regard INI makes sense, so atleast your application can initialize enough to inform you or your users the DB connection is bad.

Constants do make sense...I'm puzzled why everyone seems to say otherwise :?

The key is understanding what a constant is: Application settings/config data are NOT constants. Constants are universal in that they do not and will not ever change. If you ever need to ask whether it will change, it's likely it will, so it's not a constant.

This is ideal, however, there are times when we as developers get lazy and use constants as quick and drity adhoc hacks, for instance storing root user information in a CONSTANT but user credentials inside a database (something I'm guilty of) it allows atleast the root user gauranteed access to a system incase something goes wrong which can be fixed through administration panels (like your server admin changes your DB user/pass)

Of course this all depends on how you design and build a complex application.

Constants are the only way I can think of passing default parameters to functions:

Code: Select all

function _test($file, $data=BLANK_BUFFER);
BLANK_BUFFER to my knowledge must be a constant, not a variable stored in a DB. :P It's this or a hardcoded value, in which case if it exists more than once and has the same meaning, the using a constant makes sense :P

Cheers :)

Posted: Thu Sep 21, 2006 11:35 am
by Jenk
In response to your first pont, Hockey, that all depends entirely on table structure :)

Code: Select all

CREATE TABLE `settings`
{
    `id` INT NOT NULL AUTO_INCREMENT,
    `group` VARCHAR(20) NOT NULL,
    `name` VARCHAR(20) NOT NULL,
    `value` VARCHAR(20) NOT NULL
}
I can now run a statement to gather all related info, for say database with:

Code: Select all

SELECT `name`, `value` FROM `settings` WHERE `group` = 'DB';

Code: Select all

while ($row = mysql_fetch_assoc($result))
{
    $settings[$row['name']] = $row['value'];
}
Like you say, they are records. So we treat each setting as a record. This will allow for easy expansion.

Though I agree with your second point. A more "reliable" method should be used for settings that are vital.

Posted: Thu Sep 21, 2006 11:42 am
by Maugrim_The_Reaper
I could be reading you completely wrong Hockey - it seems you are switching argument points mid-sentence ;). Just to clarify what I think we both agree on (before I reread your post and scratch all my hair out...):

1. Constants are permanently fixed non-changeable values

This includes typical mathematical constants, ratios, and status-codes (options for example).

2. Constants are not data which has the possibility of being changed at some future point

Thus it's unsuitable to store settings, config, etc. in constants. If they are going to be changed, what's the mechanism for doing so if they are constants??? I'd put user data out there as being unsuitable for constants - they are changeable data and if you want a reliable bootstrap should be in an INI or some other format.

Just to note, I can't think of an OOP method for handling settings as constants...unless it involved a few methods like get_defined_vars() or get_defined_constants() with some array_keys() manipulation to read in constants as a separate input source to a Config object.

Posted: Thu Sep 21, 2006 12:01 pm
by s.dot
PHPBB defines a lot of them.

Code: Select all

// Debug Level
//define('DEBUG', 1); // Debugging on
define('DEBUG', 1); // Debugging off


// User Levels <- Do not change the values of USER or ADMIN
define('DELETED', -1);
define('ANONYMOUS', -1);

define('USER', 0);
define('ADMIN', 1);
define('MOD', 2);


// User related
define('USER_ACTIVATION_NONE', 0);
define('USER_ACTIVATION_SELF', 1);
define('USER_ACTIVATION_ADMIN', 2);

define('USER_AVATAR_NONE', 0);
define('USER_AVATAR_UPLOAD', 1);
define('USER_AVATAR_REMOTE', 2);
define('USER_AVATAR_GALLERY', 3);


// Group settings
define('GROUP_OPEN', 0);
define('GROUP_CLOSED', 1);
define('GROUP_HIDDEN', 2);


// Forum state
define('FORUM_UNLOCKED', 0);
define('FORUM_LOCKED', 1);


// Topic status
define('TOPIC_UNLOCKED', 0);
define('TOPIC_LOCKED', 1);
define('TOPIC_MOVED', 2);
define('TOPIC_WATCH_NOTIFIED', 1);
define('TOPIC_WATCH_UN_NOTIFIED', 0);


// Topic types
define('POST_NORMAL', 0);
define('POST_STICKY', 1);
define('POST_ANNOUNCE', 2);
define('POST_GLOBAL_ANNOUNCE', 3);


// SQL codes
define('BEGIN_TRANSACTION', 1);
define('END_TRANSACTION', 2);


// Error codes
define('GENERAL_MESSAGE', 200);
define('GENERAL_ERROR', 202);
define('CRITICAL_MESSAGE', 203);
define('CRITICAL_ERROR', 204);


// Private messaging
define('PRIVMSGS_READ_MAIL', 0);
define('PRIVMSGS_NEW_MAIL', 1);
define('PRIVMSGS_SENT_MAIL', 2);
define('PRIVMSGS_SAVED_IN_MAIL', 3);
define('PRIVMSGS_SAVED_OUT_MAIL', 4);
define('PRIVMSGS_UNREAD_MAIL', 5);


// URL PARAMETERS
define('POST_TOPIC_URL', 't');
define('POST_CAT_URL', 'c');
define('POST_FORUM_URL', 'f');
define('POST_USERS_URL', 'u');
define('POST_POST_URL', 'p');
define('POST_GROUPS_URL', 'g');

// Session parameters
define('SESSION_METHOD_COOKIE', 100);
define('SESSION_METHOD_GET', 101);


// Page numbers for session handling
define('PAGE_INDEX', 0);
define('PAGE_LOGIN', -1);
define('PAGE_SEARCH', -2);
define('PAGE_REGISTER', -3);
define('PAGE_PROFILE', -4);
define('PAGE_VIEWONLINE', -6);
define('PAGE_VIEWMEMBERS', -7);
define('PAGE_FAQ', -8);
define('PAGE_POSTING', -9);
define('PAGE_PRIVMSGS', -10);
define('PAGE_GROUPCP', -11);
define('PAGE_TOPIC_OFFSET', 5000);


// Auth settings
define('AUTH_LIST_ALL', 0);
define('AUTH_ALL', 0);

define('AUTH_REG', 1);
define('AUTH_ACL', 2);
define('AUTH_MOD', 3);
define('AUTH_ADMIN', 5);

define('AUTH_VIEW', 1);
define('AUTH_READ', 2);
define('AUTH_POST', 3);
define('AUTH_REPLY', 4);
define('AUTH_EDIT', 5);
define('AUTH_DELETE', 6);
define('AUTH_ANNOUNCE', 7);
define('AUTH_STICKY', ;
define('AUTH_POLLCREATE', 9);
define('AUTH_VOTE', 10);
define('AUTH_ATTACH', 11);


// Table names
define('CONFIRM_TABLE', $table_prefix.'confirm');
define('AUTH_ACCESS_TABLE', $table_prefix.'auth_access');
define('BANLIST_TABLE', $table_prefix.'banlist');
define('CATEGORIES_TABLE', $table_prefix.'categories');
define('CONFIG_TABLE', $table_prefix.'config');
define('DISALLOW_TABLE', $table_prefix.'disallow');
define('FORUMS_TABLE', $table_prefix.'forums');
define('GROUPS_TABLE', $table_prefix.'groups');
define('POSTS_TABLE', $table_prefix.'posts');
define('POSTS_TEXT_TABLE', $table_prefix.'posts_text');
define('PRIVMSGS_TABLE', $table_prefix.'privmsgs');
define('PRIVMSGS_TEXT_TABLE', $table_prefix.'privmsgs_text');
define('PRIVMSGS_IGNORE_TABLE', $table_prefix.'privmsgs_ignore');
define('PRUNE_TABLE', $table_prefix.'forum_prune');
define('RANKS_TABLE', $table_prefix.'ranks');
define('SEARCH_TABLE', $table_prefix.'search_results');
define('SEARCH_WORD_TABLE', $table_prefix.'search_wordlist');
define('SEARCH_MATCH_TABLE', $table_prefix.'search_wordmatch');
define('SESSIONS_TABLE', $table_prefix.'sessions');
define('SESSIONS_KEYS_TABLE', $table_prefix.'sessions_keys');
define('SMILIES_TABLE', $table_prefix.'smilies');
define('THEMES_TABLE', $table_prefix.'themes');
define('THEMES_NAME_TABLE', $table_prefix.'themes_name');
define('TOPICS_TABLE', $table_prefix.'topics');
define('TOPICS_WATCH_TABLE', $table_prefix.'topics_watch');
define('USER_GROUP_TABLE', $table_prefix.'user_group');
define('USERS_TABLE', $table_prefix.'users');
define('WORDS_TABLE', $table_prefix.'words');
define('VOTE_DESC_TABLE', $table_prefix.'vote_desc');
define('VOTE_RESULTS_TABLE', $table_prefix.'vote_results');
define('VOTE_USERS_TABLE', $table_prefix.'vote_voters');

Posted: Thu Sep 21, 2006 4:32 pm
by matthijs
That is quite a list.

In many/some apps you'll see these settings "defined" as variables, like $setting['user_can_post'] = '1'; etc.

So basicly we have 3 choices.
1) List of constants, like scottayy shows
2) list of variables (my example), in a normal php file or extracted from an xml
3) db table (jenk's example)
Isn't it?

But as far as I have understood, defining a lot of constants is slow as hell. But that's only from reading some threads here and there, never tested anything.

Posted: Fri Sep 22, 2006 4:24 am
by Maugrim_The_Reaper
Constants are slower - not sure of the exact ratio in performance but AFAIK it's pretty steep. Banging those into a function and measuring it with XDebug might get an answer - might do that later to compare and get real numbers...

Another thought - defining constants for config values seems a bit of a "get-out" in terms of Constants being essentially similar to Globals for certain uses. If Globals are bad (not just for security reasons) replacing them with constants isn't much better.

Posted: Fri Sep 22, 2006 1:14 pm
by alex.barylski
Maugrim_The_Reaper wrote:Constants are slower - not sure of the exact ratio in performance but AFAIK it's pretty steep. Banging those into a function and measuring it with XDebug might get an answer - might do that later to compare and get real numbers...

Another thought - defining constants for config values seems a bit of a "get-out" in terms of Constants being essentially similar to Globals for certain uses. If Globals are bad (not just for security reasons) replacing them with constants isn't much better.
Bingo...thats the basis that everyones argument on using CONSTANTS as being bad is all about and a global and constant couldn't be further from the same thing.

Globals are dangerous, because their state/value can be changed anywhere in code indirectly which could lead to awefully difficult to find bugs - personally I have *never* encountered this problem, but meh...who am I to say? :P

Constants are completely immutable, they are a language construct/modifier which enforces this rule.

It is impossible (in languages that I know of) to utilize a variable as a default argument value, constants/macros/defines, etc are a way of specifying a default argument without hardcoding the value right into the argument itself.

Code: Select all

function _test($test=100);
function _test($test=MY_CONSTANT);
Constants prevent any change dynamically at runtime, so option bits for example are *best* defined using constants, not registries or other forms of immutable objects.

Unlike application settings, option bits cannot or at least should not change every. If you assign an account as active using the first bit of your option field, that bit is perpetually reserved.

It simply does not make sense to use any other method except constants/defines...

Cheers :)

Posted: Fri Sep 22, 2006 1:26 pm
by feyd
If I need something constant, I'll make it an object level constant so it has a namespace.

Code: Select all

class floob
{
  const INTELLIGENT = 'inteligente';
  const GOOD = 'bueno';
}