what constants do you define?

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

Hockey, were you drinking when you posted that? 8O
User avatar
n00b Saibot
DevNet Resident
Posts: 1452
Joined: Fri Dec 24, 2004 2:59 am
Location: Lucknow, UP, India
Contact:

Post by n00b Saibot »

Everah wrote:Hockey, were you drinking when you posted that? 8O
is that Hockey, i thought that was cockey :lol:
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post 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...
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post 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).
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post 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)
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post 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.
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post by matthijs »

Ok thanks Maugrim, I'll imprint your advice in my memory
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post 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 :)
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post 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.
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post 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.
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post 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');
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post 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.
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post 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.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post 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 :)
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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';
}
Post Reply