Jump to content

NotionCommotion

Members
  • Posts

    2,446
  • Joined

  • Last visited

  • Days Won

    10

Everything posted by NotionCommotion

  1. Ended up changing the Configuration class to support multiple levels. class Configuration { private static $instance = NULL; private function __construct() {} //Make private private function __clone(){} //Make private private static function init() { $config = parse_ini_file("../../application/config.ini",true); self::$instance=$config; } public static function getOther($prop) { if (!self::$instance){self::init();} return self::$instance['other'][$prop]; } public static function getAccess($prop) { if (!self::$instance){self::init();} return self::$instance['access'][$prop]; } }
  2. For instance, something like the following: <?php class Configuration { private static $instance = NULL; private function __construct() {} //Make private private function __clone(){} //Make private public static function getSetting($prop) { if (!self::$instance) { $config = parse_ini_file("../../application/config.ini"); self::$instance=new stdClass(); foreach($config as $key=>$value) { self::$instance->$key=$value; } } return self::$instance->$prop; } } class Request { public static function isJavaScriptEnabled() { return isset($_SESSION['TIMESTAMP']) && isset($_COOKIE['TIMESTAMP']) && $_SESSION['TIMESTAMP']==$_COOKIE['TIMESTAMP']; } public static function isHTTPS() { return ( (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') || $_SERVER['SERVER_PORT'] == 443 ); } public static function isAsync() { return isset($_POST['is_async'])?$_POST['is_async']:(isset($_GET['is_async'])?$_GET['is_async']:(isset($_SERVER['HTTP_X_REQUESTED_WITH'])?$_SERVER['HTTP_X_REQUESTED_WITH']:false)); } public static function getRequestedContent() { return isset($_GET['request_type'])?$_GET['request_type']:(isset($_POST['request_type'])?$_POST['request_type']:'text'); } public static function getPrimaryDomain($domain) { return $domain[count($domain)-2].'.'.$domain[count($domain)-1]; } public static function getURI() { return (self::isHTTPS?'https':'http').'://'.$_SERVER['HTTP_HOST']; } public static function getCSRF() { return isset($_SESSION['CSRF'])?$_SESSION['CSRF']:null; } public static function getPreviousTimestamp() { return isset($_SESSION['TIMESTAMP'])?$_SESSION['TIMESTAMP']:null; } public static function getTimestamp() { //Get rid of this one, and use $_SERVER['REQUEST_TIME'] return time(); } } class App { public static function getLibPath() { //return library path, etc } } //will parse file echo(Configuration::getSetting('TIMEZONE').'<br>'); //will not parse file echo(Configuration::getSetting('LOCALITY').'<br>'); ?>
  3. Thanks Jacques1, I appreciate and agree with your advice. Since the data is static, would you recommend a static class, or a traditional class where the objects are passed to those classes that need them?
  4. Your original script at the end just displays the errors as a group. Note that this is typically how I do it. I agree that error prompts at the individual fields are nice, and I use jQuery validation plugin for client "nice" validation before validating serverside, so most people don't see the list of errors. if(!empty($errors)){ foreach($errors as $error){ echo '<span style="color: red">'.htmlspecialchars($error).'</span>'.'</br>'.'</br>'; } } As for as $errors[]=""; goes, you shouldn't be doing this. Doing so just adds another element to the array. Even though PHP doesn't require, I always define an empty array using $errors=array(); before adding elements to it. Get to know and appreciate var_dump(). Or, if you prefer (I often do), use the following: echo('<pre>'.print_r($errors,1).'</pre>');
  5. Ha ha, beat you twice in a row
  6. Agree with QuickOldCar, but I wouldn't use associated arrays.
  7. Be careful regarding how much JavaScript you generate with PHP. It could become a troubleshooting nightmare. Some believe it should never be done, but I defining a couple of variables is acceptable, and then using your static JavaScript to react to those variables.
  8. $nameErr = "The form of the name entered is not acceptable"; along with all your other errors needs to be changed to $errors[]= "The form of the name entered is not acceptable";
  9. I agree all these constants are even less modular, and I feel my approach is somewhat inherently wrong. I have defined about 50 constants, and use them over 1,000 locations in a given application, and it is rather overwhelming. Let me explain where I use them. Defining filesystem paths such as the location of my classes, etc. I suppose this is okay. Defining configuration constants which are obtained from my previously mentioned parsed configuration file. This seems like a waste. Defining stuff about the request such as the protocol or requested content. This is probably not ideal. Defining two special constants which identify the account and the user. This is probably not right, but it seems to make life easier. How wold you recommend changing it? <?php //Define file locations define( 'DS', DIRECTORY_SEPARATOR ); define('USR_CLASSES',__DIR__); define('USR_APPLICATION_BASE',dirname(USR_CLASSES)); define('USR_ROOT_BASE',dirname(USR_APPLICATION_BASE)); define('USR_TWIG',USR_ROOT_BASE.'/vendor/autoload.php'); define('USR_LIB',USR_APPLICATION_BASE.DS.'lib'); define('USR_HELP',USR_LIB.DS.'help'); define('USR_TEMPLATES',USR_LIB.DS.'templates'); define('USR_HTDOCS_BASE',USR_ROOT_BASE.DS.'html'); define('USR_RESOURCES_BASE',USR_ROOT_BASE.DS.'user_resources'); define('USR_DOCUMENTS_USER', USR_RESOURCES_BASE.DS.'documents'); define('USR_DOCUMENTS_TMP', USR_RESOURCES_BASE.DS.'tmp'); define('USR_DOCUMENTS_TMPSAVE', USR_RESOURCES_BASE.DS.'tmpsave'); define('USR_OS_TICKET',USR_HTDOCS_BASE.DS.'support'); //Set configuration constants $this->init = parse_ini_file(USR_APPLICATION_BASE."/config.ini"); define('USR_PASSWORD_ALGORITHM',$this->init['PASSWORD_ALGORITHM']); define('USR_PASSWORD_COST',$this->init['PASSWORD_COST']); define('USR_GOOGLE_MAP_KEY',$this->init['GOOGLE_MAP_KEY']); define('USR_IPINFODB_KEY',$this->init['IPINFODB_KEY']); define('USR_RECAPTCHA_PUBLIC', $this->init['RECAPTCHA_PUBLIC'] ); define('USR_RECAPTCHA_PRIVATE', $this->init['RECAPTCHA_PRIVATE'] ); define('USR_MEMORY_LIMIT',$this->init['MEMORY_LIMIT']); define('USR_MAX_FILE_SIZE_BACK',$this->init['MAX_FILE_SIZE_BACK']); define('USR_MAX_FILE_SIZE_FRONT',$this->init['MAX_FILE_SIZE_FRONT']); define('USR_MAX_FILE_SIZE_UPLOAD_RECORDS',$this->init['MAX_FILE_SIZE_UPLOAD_RECORDS']); define('USR_PUBLIC_ACCESS_ID',$this->init['PUBLIC_ACCESS_ID']); define('USR_USER_ACCESS_ID',$this->init['USER_ACCESS_ID']); define('USR_ADMIN_ACCESS_ID',$this->init['ADMIN_ACCESS_ID']); define('USR_TECHSUPPORT_ACCESS_ID',$this->init['TECHSUPPORT_ACCESS_ID']); define('USR_ROOT_ACCESS_ID',$this->init['ROOT_ACCESS_ID']); define('USR_PRIVATE_SALT',$this->init['PRIVATE_SALT']); define('USR_RANKING_CONSTANT',$this->init['RANKING_CONSTANT']); define('USR_COMPONENTS_BASE',USR_APPLICATION_BASE.DS.'components'.DS.'back'); define('USR_MAX_TOTAL_LOGON_ATTEMPTS',$this->init['MAX_TOTAL_LOGON_ATTEMPTS_BACK']); define('USR_LOGONS_HOURS_IP_BAN',$this->init['LOGONS_HOURS_IP_BAN_BACK']); define('USR_MAX_IP_LOGON_ATTEMPTS',$this->init['MAX_IP_LOGON_ATTEMPTS_BACK']); define('USR_LOGONS_HOURS_BAN',$this->init['LOGONS_HOURS_BAN_BACK']); define('USR_MAX_LOGON_ATTEMPTS',$this->init['MAX_LOGON_ATTEMPTS_BACK']); //Define stuff about the request define('USR_PROTOCOL',( (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') || $_SERVER['SERVER_PORT'] == 443 )?'https':'http'); define('USR_PRIMARY_DOMAIN', $domain[count($domain)-2].'.'.$domain[count($domain)-1]); define('USR_URI', USR_PROTOCOL.'://'.$_SERVER['HTTP_HOST']); define('USR_CSRF',isset($_SESSION['CSRF'])?$_SESSION['CSRF']:null); define('USR_TIMESTAMP',time()); define('USR_TIMESTAMP_OLD',isset($_SESSION['TIMESTAMP'])?$_SESSION['TIMESTAMP']:null); define('USR_JAVASCRIPT_ENABLED',isset($_SESSION['TIMESTAMP']) && isset($_COOKIE['TIMESTAMP']) && $_SESSION['TIMESTAMP']==$_COOKIE['TIMESTAMP']); define('USR_CONTENT_REQUEST',isset($_GET['request_type'])?$_GET['request_type']:(isset($_POST['request_type'])?$_POST['request_type']:'text')); define('USR_IS_ASYNC',isset($_POST['is_async'])?$_POST['is_async']:(isset($_GET['is_async'])?$_GET['is_async']:(isset($_SERVER['HTTP_X_REQUESTED_WITH'])?$_SERVER['HTTP_X_REQUESTED_WITH']:false))); //Define special two constants define('USR_ACCOUNT_ID',$this->accountData->id); define('USR_USERS_ID',$this->userData->id); ?>
  10. I agree. But is defining a bunch of constants (which I currently do) any better? Okay, but with all due respect, so what? Granted, I've never attempted to do unit testing, and am likely off base. But I just don't understand how this is different than defining a constant.
  11. You mean this discussion: http://forums.phpfreaks.com/topic/292592-alternatives-to-globals/?hl=%2Bdependency+%2Binjection&do=findComment&comment=1497323? Please elaborate on the downsides of having to hard-coded reference to this specific class. I get why one shouldn't have some global variable where a bunch of methods read and modify at will, and that is not my intention, but only to have access to various configuration "constants".
  12. Not mostly procedure code. I follow my self styled MVC architecture (probably sucks, but it seems to work for me. My concepts originated from "yikes" Joomla, but has vastly diverted). My initial script (index.php with a couple of classes to assist) is rather procedure based, and figures out which controller to use and invokes it. Controller does some logic, gets some data from the model, and passes it to a Twig template (thanks by the way). I also have some general library type classes, but suppose I could pass the configuration settings to them as needed. So, really just the controller classes and model classes need access to it (the Twig views and general library classes will be passed the data when needed). So one option is pass the settings to the controller, and have it in turn pass them to the model via constructors? Would the settings then be assessed as $this->Configuration->bla in both the controllers and models? What would using hard-coded reference to some Configuration class which has static methods for getting a configuration value look like?
  13. I have a configuration file, and I use parse_ini_file() to parse it into an array at the initial entry point of my script. I would like the settings to be available to all downstream scripts/methods/functions. Note that my intent is not to change them outside of the configuration file, and ideally they will be readonly, however, if not, I suppose that is okay and I will just be sure not to modify them. I've read about dependency injection, and while this mostly makes sense, it seems like a lot of script/troubleshooting for little if any value for this scenario. I've read that global variables are bad (couples your objects to some "god" object, cannot unit test, difficult to troubleshoot, difficult to work with multiple developers, potential conflicts with other classes, namespace pollution), but maybe not for this case? Another option is defining a bunch of constants to the appropriate values, but this seems redundant. Or maybe some static class with all the values? What would be the best way to make configuration settings available to all PHP scripts, functions, and methods?
  14. Not really sure what you are trying to do. The browser/client has some data, and posts it to the server. The server does what ever you tell it to do, and inserts data into the DB. PS. You know this is really bad, right? If you don't know why, search for "SQL injection". where cilindro = ".$_POST['sel_cil']." and esfera = ".$_POST['sel_esf']." and id_lente =". $_POST['sel_lente'];
  15. I would expect BINARY would be more efficient, however, wouldn't it need to be converted using either PHP's hex2bin() or MySQL's UNHEX()? <?php $password='rasmuslerdorf'; echo($password."<br>"); $hash=password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]); echo($hash."<br>"); $binary_hash=hex2bin($hash); echo($binary_hash."<br>"); ?> rasmuslerdorf $2y$12$GkCH8rRmTfHuBFG/WEdPbuULI29p7vKCHlt2o7w3dkvtgeXlFsLja Warning: hex2bin(): Input string must be hexadecimal string in /var/www/main/html/testing/hashing2.php on line 6
  16. Hi Hansford and QuickOldCar, I ended up going away from using PASSWORD_DEFAULT, and will explicitly use PASSWORD_BCRYPT. As such, it will always be 60 characters. If I later elect to change algorithms, I will change the database schema at that time. That being the case, I would expect I would want to use CHAR(60) or maybe some sort of BINARY.
  17. http://php.net/manual/en/function.password-hash.php shows a simple example to hash a password using BCRYPT. I've read different posts recommending CHAR(60), BINARY(60), BINARY, and even BINARY(40). What are the pros and cons of using one datatype over another? <?php /** * In this case, we want to increase the default cost for BCRYPT to 12. * Note that we also switched to BCRYPT, which will always be 60 characters. */ $options = [ 'cost' => 12, ]; echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options)."\n"; ?>
  18. Thank you Jacques1, Good explanation. If usernames are case insensitive, why worry about needing similar-looking characters to be considered equal? In regards to hiding the fact that a username exists, wouldn't the only users who witness the long hash computation time be those who successfully logged in with their credentials? I suppose I can do a fake hash for non-authenticated users, but doesn't seem to bring any value. Also, based on my general webbrowsing experience, some requests just take longer due to server load, network traffic, etc. How can one attribute a delay to a specific cause such as a password hash?
  19. You are updating every record in your table. You need a WHERE clause that limits it to just the applicable PK.
  20. What are the columns in the uploads table? Does it have a primary key? Also, you are not doing your prepared statements correct! You do not put the values in the query but add placeholders in the query (either ? or :name), and pass the values as an array to the execute method. Yes, your query will work, but it is not escaping anything.
  21. Same reason this works: class A extends B{} class C{} class B extends C{} and this doesn't: class A extends B{} class B extends C{} class C{} I don't know the specifics, but per http://php.net/manual/en/keyword.extends.php: Granted, one would expect the first example not to work. Better off always putting them in order.
  22. Without knowing your database schema, it is impossible to answer. I would expect, however, that you should just do three queries.
  23. Not a bug, just the way it is. If a class is being extended more than once, you need to put the classes in order so that when PHP interprets code, it is aware of the class.
  24. Implying that the application should update the users hashed password in the database every time they log in? I've never done so, but it seems to be a good idea. Not only will the cost be updated, but should there be any bugs in the algorithm, the hashes will be updated, and furthermore the algorithm could be updated if changed. Do you recommend using PASSWORD_DEFAULT (which is currently the same as PASSWORD_BCRYPT and CRYPT_BLOWFISH)? If so, what datatype would you recommend in the database? http://php.net/manual/en/function.password-hash.php recommends 255 characters. Would this be varchar(255), char(255), or maybe some sort of binary? Would the flow be the following? Note my inline question regarding trimming and removing of invalid characters in username and password. <?php //GIVEN: $POST=array('username'=>'john.doe','password'=>'my password') //Maybe don't do this as whitespace should be acceptable in username and password? //Also, are there any characters which should be removed from either username or password? $username=trim($_POST['username']); $password=trim($_POST['password']); //Actually use atomic counter as described http://forums.phpfreaks.com/topic/293061-validate-username-and-password/?p=1499458 $sql='SELECT hash FROM users WHERE username=?'; $stmt=db::db()->prepare($sql); $stmt->execute(array($username)); if(password_verify ($password, $stmt->fetchColumn() )) { $cost=12; //Actually get from configuration file $hash=password_hash($password, PASSWORD_DEFAULT, ['cost' => $cost]); $sql='UPDATE users SET hash=? WHERE username=?'; $stmt=db::db()->prepare($sql); $stmt->execute(array($hash,$username)); //redirect as applicable } else { //display invalid username/password error and display login prompt } ?>
  25. Yes! It is called JOIN. SELECT t1.this, t2.that, t3.andThis FROM table_1 AS t1 INNER JOIN table2 AS t2 ON t2.table_1_id LEFT OUTER JOIN table3 AS t3 ON t3.table_2_id=t2.id WHERE t1.bla=123;
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.