rwhite35
Members-
Posts
159 -
Joined
-
Last visited
Everything posted by rwhite35
-
Replace Characters Algorithm with O(n) Time/Complexity Notation
rwhite35 replied to rwhite35's topic in PHP Coding Help
Yes that could be the case. I don't think there is a right or wrong answer per se' and I'm really doing this for my own "enjoyment" and education. But yes, some sort of search mechanism could potentially be another solution. The book is the Wrox Programmer to Programmer series and titled Programming Interviews Exposed. It doesn't really give any hard solution to the problems it poses, just boundaries and general direction. -
Replace Characters Algorithm with O(n) Time/Complexity Notation
rwhite35 replied to rwhite35's topic in PHP Coding Help
Thanks for the feedback. I'll work in the direction of your second pseudocode ( O(log m) ). That seems more intuitive then what I was proposing. Appreciate the feedback, that's a big help. -
Reading a CompSci book and it gives problems requiring algorithms WITHOUT the use of (lang.) build in function. In the following problem, the process should remove characters in a string using a set of target characters. It should be able to do this in one pass - or O(n). According to the book, there is a solution - though I'm skeptical and the book is using Java. The following function employs PHP built in functions and works as required, in one pass. function removeWithBuiltin($string,$chr,$replacement) { foreach($chr as $v) { // O(1) $part = $v."|"; $pattern = $pattern . $part; // example a|k|e|x } $pattern = rtrim( $pattern, "|" ); //trim off last vertical bar $pattern = "/".$pattern."/"; $string = preg_filter($pattern, $replacement, $string); // O(1) var_dump($string); } The following class is functionally the same as the above. It returns the same string as removeWithBuiltin(). class stringEditor { public $inputStr; // string to edit public $newStr; // string to return public $rmSet; // array, unknown set of characters to remove public function __construct($str,$rArr) { $this->inputStr = $str; $this->rmSet = $rArr; } /* * removeChar loops through input array and compares each remove target character to its value, * if value and target are equal, assign null to buffer; else assign value to buffer * return array $buffer, processed input characters minus this removed character target (if any) */ protected function removeChar($strArr,$chr) { $buffer = array(); $cnt = count($strArr); for( $i=0; $i<$cnt; $i++ ) { // eval each character, highest term O($i) $buffer[$i] = ( $strArr[$i] == $chr ) ? null : $strArr[$i]; } if(!empty($buffer)) { return $buffer; } else { return $strArr; } } /* * converts input string to indexed array and calls an instance of * removeChar with string array and each character to search and replace with null value * return string $editString, input string without removed characters */ public function processString() { $strArray = str_split($this->inputStr); // convert string to array of chars foreach ($this->rmSet as $char) { // eval each character in the remove set $e=0; if (empty($this->newStr)) { // initial condition, $this->newStr doesnt exist $this->newStr[] = $this->removeChar($strArray, $char); } else { // now use previous and call removeChar, overloading 0 with each loop $this->newStr[0]= $this->removeChar($this->newStr[$e], $char); $e++; } } /* * flatten $this->newStr array object in to a string * prototype: array([0]=>array([0]=>char, [1]=>char, ... )) */ $array = $this->newStr[0]; // overloaded all previous edits for($i=0; $i<count($array); $i++) { $editString = $editString . $array[$i]; } if(isset($editString) && !empty($editString)) {return $editString;} else {return false;} } } // close class This class takes "n" number of characters to remove characters from a given string "t" characters long. So its notation should be O(log n^t); or possible O(n * t), but not O(n). And finally, here is the questions: Any thoughts on how this class could be modified to only loop over the input string - once - removing an unspecified set of characters? Here is the test parameters: $randomString = "bucked the science from popular"; $chars = [ "a", "k", "e", "x" ]; $removeObj = new stringEditor( $randomString, $chars ); $results = $removeObj->processString(); echo $results; // outputs bucd th scinc from populr Some direction on how to improve the performance of the class would be appreciated.
-
Thanks for the reply. Been busy. I do use Composer for some projects, mainly ZendFramework projects. But wanted something light weight and simple to configure for my own projects. Appreciate the feedback, thanks.
-
Is this the correct implementation of a mvc service layer?
rwhite35 replied to ICJ's topic in Application Design
Some general comments. M-V-C is ideal in team situations where you have multiple developers working on a similar problem. Also, when building a framework or API where you plan to give other scripts or users access to certain features/functions. In either instance, its very helpful when the code has strict adherence to the M-V-C paradigm. If this is your own application and you don't expect to have other interact with your code, then having lax adherence (ie Service Layer) to M-V-C is personal preference. As for the script block above, it's hard (for me at least as an "outsider") to tell what's going on without see the implementation and/or application structure. But if I were trying to explain M-V-C to someone, I would use the following scenario. It helps to think about such abstractions in real world terms. SCENARIO: Web user rents linens for her restaurant through a website. She logs into the ordering system and is presented with a catalog of linens. The system defines a default behavior which is to present a catalog of linens (including her previous order). The model first checked to determine if she was authorized to view the catalog. Once satisfied, the model pulls all the relevant linen data; and her last purchase order. The model returns raw data objects to the controller. The controller takes the raw data and processes the information in to formatted data objects. The controller applies filtering rules based on her ordering preferences and other routine functions. The data is stored in transport objects passed to the viewer for output. The viewer creates an instance of the data objects through an interface method (typically defined in the controller) and outputs the result into document objects (DOM) ie product info with an images in some container element. ./catalog.php |_ catalog/src/cat_viewer.php |_ catalog/src/cat_controller.php (includes catalog/lib/cat_model.php) |_ database As both a PHP and Java developer, I find this structure to be the most common. I doubt this answers your question, but hopefully it give some feedback. -
Would like some thoughts about this autoloader for namespaces. Its loosely based on Zend Framework 2 using Composer. I wanted a simple loader for including my custom classes(ie DB connection, list and forms generations etc) in application modules. Autoloader works as expected so no error to debug, but looking more for improvements or gotcha's I'm not aware of. This is pseudo code, but the machinery is what's important. ./controller_script.php /* initializes Autoload with an array of namespace strings */ include 'init_autoloader.php'; /* from testspaces.php */ echo Testspaces\Autoload\Tsclass::printSomething(); // outputs This is a simple string. /* from globalspaces.php */ echo Globalspaces\Autoload\Omnipresent::imEverywhere(); //outputs This is a good hand. ./init_autoloader.php /** * initialize the autoloader for namespaces under the lib directory. * this script would be placed in each module where global classes * were required, ie DB connections, UI output(lists and forms) */ /* namespaces array, namespace file name matches first part before first backslash */ $nsarray = array( 'Globalspaces\Autoload\Omnipresent', 'Testspaces\Autoload\Tsclass', ); /* initialize the AutoloaderInit class */ $apath = __DIR__ . "/lib/autoload.php"; if (file_exists($apath)) { include $apath; $loaderObj = new AutoloaderInit($nsarray); $loaderObj->getLoader(); } else { echo "Missing autoload.php script, check file path: ".$apath."<br>"; } lib/autoload.php class AutoloaderInit { private static $loader; private static $nsnames; // indexed array of namespace strings defined in init_autoloader public function __construct($nsarray) { self::$nsnames = $nsarray; } /* * callback function called by spl_autoload_register * $class passed by reference */ public static function loadClassLoader($class) { if ($class) { $nameparts = explode('\\', $class); $filename = strtolower($nameparts[0]).".php"; require __DIR__ . DIRECTORY_SEPARATOR . $filename; } else { throw new Exception("loadClassLoader failed to include ".$filename); } } /* * interface method called from initializer * $params array $nsnames, array of namespace strings * $return void */ public static function getLoader() { //error_log("getLoader nsnames: ".var_dump(self::$nsnames)); if (self::$nsnames) { $cnt = count(self::$nsnames); for($i=0;$i<=$cnt;$i++) { if (null !== self::$loader) return self::$loader; spl_autoload_register(array('AutoloaderInit', 'loadClassLoader'), true, true); self::$loader = $loader = new self::$nsnames[$i]; // new instance of class } // close for loop spl_autoload_unregister(array('AutoloaderInit', 'loadClassLoader')); return $loader; } else { error_log("No namespaces provided to getLoader"); } } } lib/testspace.php namespace Testspaces\Autoload; /* a class defined in namespace */ class Tsclass { static function printSomething() { echo "This is a simple string.<br>"; } } lib/globalspaces.php namespace Globalspaces\Autoload; /* another class defined in namespace */ class Omnipresent { static function imEverywhere() { echo "This is a good hand.<br>"; } }
-
Okay, you could shorten the process with this modification. It only evaluates one element of the associative array. for ($i=0;$i>=count($Array);$i++) { // loop through indexed array $Url = ($Array[$i]['Purpose'] == $string) ? $Array[$i]['Uri'] : null; // assign url to variable if $string is thumbnail }
-
First you have a multi-dimensional array, an array or arrays. In your case the first array is indexed. So you can deal with that array using a for loop. The array inside the indexed array is associative, so you can deal with that array using the foreach. Using for outer/inner looping construct: for ($i=0;$i>=count($Array);$i++) { // loop through each indexed array foreach ($Array[$i] as $key=>$value) { // loop through each associative array $Url = ($value == $string) ? $Array[$i]['Uri'] : null; // assign url to variable if $string is thumbnail } }
-
How to transform a codebase to use modern DB-access practices?
rwhite35 replied to dennis-fedco's topic in PHP Coding Help
Here is an anonymous db query class I use for SELECT and DELETE actions. Its algorithmic, it will take the query, optimize it, bind the tokens and return a result. Note the protected property, this class was written to be called from within another class. Its method querydb is only available to the class from which it was called. To make dbmanager::querydb available to scripts outside another class, you'll want to change protected fucntion querydb to public. Whether called from a class or from the script, you would query the database with something like: include( "dbmanager.class.php" ); // path to dbmanager class $query = "SELECT * FROM sales.item WHERE id=?"; $bind = $orderid; $qryObj = new dbmanager(); $result = $qryObj->querydb( $query, $bind ); print_r($result); $result will be the query result, either an array or boolean(true/false). Using this pattern, you can probably use most of your SELECT and DELETE statements without a lot of refactoring. Just instance a new class each time you want a data pull. Just instantiate another $results variable each time you want another query: $qryObj = new dbmanager(); $result1 = $qryObj->querydb( $query1, $bind1 ); $result2 = $qryObj->querydb( $query2, $bind2 ); Here is the class: class dbmanager { protected $query; protected $result; protected $bind; /* * connection method. return object $DB, db connection * requires PDO driver */ protected function conn() { require '../DB_CONF.inc'; // text file with db credential constants try { $DB = new PDO(DB_HOST, DB_UNAME, DB_UPWORD); $DB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch( Exception $e ) { $mes = "Error:dbmanager Caught Exception ---"."\n"; $mes .= $e->getMessage()."\n"; error_log($mes); } return $DB; } /* * protected querydb method * param string $query, query statement passed from calling class * param mixed $bind, indexed array or scalar variable contains WHERE tokens(?), * !!important, the field order and placeholders must match up!! * return mixed $result, array or boolean */ protected function querydb($query,$bind) { $DB = (!isset($DB)) ? $this->conn() : $DB; try { $stmt = $DB->prepare($query); if ($bind!=null) { $cnt = count($bind); if ($cnt>1) { // mulitple tokens $t=1; // binding starts with 1 for($i=0;$i<$cnt;$i++) { $stmt->bindParam($t,$bind[$i]); $t++; } } else { //single binder $stmt->bindParam(1,$bind); } } if($stmt->execute()) { // run the query while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $this->result[] = $row; } return $this->result; } else { throw new Exception("Error on dbmanage::query execution."); } } catch ( Exception $e ) { error_log("Error on query method: ".$e->getMessage()); } unset($stmt); unset($this->result); } } -
Yes. I see you are reading the file into $content and then storing the binary in the DB. Couple things, is the data type for the "data" field "blob"? It may be that the binary is getting corrupted or cut off in the process. Also, there are file size limitations with 2M being the default size for most distros. Are your files over that limit? I find it much simpler (and more common) to move the temporary file to a permanent directory and in the process give the file a programmatic name. Then in my database, I'll store the file path, original file name and update the record with the programmatic name and file extension.
-
Are you sure your path information is returned as you expect it? Also, whenever I need to generate an image file, I'm using something like this: if ($fext=="jpg" || $fext=="jpeg") { $grfx_obj = imagecreatefromjpeg($fpath); } elseif ($fext=="png") { $grfx_obj = imagecreatefrompng($fpath); imagesavealpha($grfx_obj, true); //preserve background transparency imagealphablending($grfx_obj, false); //don't blend grapic pixels with background } else { throw new Exception('GD imagecreate* failed.'); } I've used imagecreatefromstring before but I recall it was buggy or there was some obscure quark, where fromjpeg or frompng worked better for my situation.
-
Good point... That's me over under thinking things... The code is valid but confusing. It would benefit from simplifying the query statement. Not to mention input validation/sanitizing etc. etc... But yes, my bad.
-
Change this - '".$_POST["vis_name"]."', to this - $_POST['vis_name'], The double quotes are messing up the query statement. Also, it would be a better practice to use some sort of filter sanitizing function provided by PHP. I prefer the following $visName = filter_var($_POST['vis_name'], FILTER_SANITIZE_SPECIAL_CHARS); There are others, check the manual http://us3.php.net/manual/en/filter.filters.sanitize.php
-
As a side note, if your database interaction is limited to one to two queries, or if you're comfortable with procedural(or Object Oriented) style, mysqli_ is good for that. If you prefer Object Oriented; or need to use multiple database drivers (mysql, prostgresql, etc) in one application; or need to use transactions, PDO is your choice. Pick the best API (mysqli or PDO) for the right job. Both mysqli and PDO have optimization when used with prepared statements. PDO does offer more flexibility with results and transactions are a nice feature when you need to do more than one process during your script execution.
-
Sessions? How to secure pages for only logged in users
rwhite35 replied to FatesCall's topic in PHP Coding Help
Fortunately, its a slow day... Keep in mind your original post mentioned sessions, you'll still want to assign the password or user to the session as described above. $user = "john doe"; $password = 1234; $pass=null; $users = ["User1" => "123","User2" => "1234","User3" => "1235"]; if($user && $password) { foreach($users as $key=>$value) { if($value == $password) $pass=$key; } if($pass != null) { //assign to session variable here, before you redirect, //assumes session started immediately after PHP open tag $_SESSION['user']=$users[$pass]; echo "<div class="."success".">Successful. Redirecting you in 3 seconds.</div>"; echo "<meta http-equiv="."refresh"." content="."3;URL=panel.php".">"; } else { echo "<div class="."warning".">Error: Username or Password is incorrect!</div>"; } } else { echo "<div class="."warning".">Error: Username or Password is incorrect!</div>"; } -
Sessions? How to secure pages for only logged in users
rwhite35 replied to FatesCall's topic in PHP Coding Help
I think you'll need to look at line 42. The condition will never be met... Here's why. The keys for $users array are string type with a value of "User1, User2 and User3". However the function array_key_exists will compare your form $_POST['user'] value (assigned to $user). So as an example, it should compare the string "123" to the strings "User1, User2, User3"... It should return false. Try this instead: $pass=null; foreach($users as $key=>$value) { //compare users array to form field user if($value==$password) $pass=$key; //assign the $users[$key] to $pass } if ($pass!=null) { //should be something like User1, User2 or User3 $_SESSION['user']=$users[$pass]; //assign users password to session } /* continue on with your processing */ Then on subsequent pages session_start(); if(!isset($_SESSION['user'] || empty($_SESSION['user']) { //not set or empty value session_destroy(); header("Location: error.php"); //sent to UI error reporting exit(); } -
Delemma, Expose (or not) App Security Holes to Prospective Clients
rwhite35 replied to rwhite35's topic in Application Design
Great feedback gents! I'll probably share some documentation identifying the problem code. They can then pass that along to the vendor if they feel the hole is significant enough. Up till now, I've been using the insight more for my education (as in what not to do) then a means to sell a service. But in some instances, the hole was a security liability and should be fixed. Any input is appreciated. -
I'm running across this more and more. Prospective client gives access (w/o NDA) to (relatively) secure solution for the purpose of generating a project specification and project estimate. Usually the SOP is some add-on module or feature enhancement - in other words, not a major overhaul of the current solution. In the due diligence, security holes are discovered, to varying degrees of insecurity. This really becomes an awkward situation when the current solution is provided by a third party OEM and leased by the client. To make matters worse, the prospective client decides NOT to proceed with the project so there is no financial benefit to giving away consulting services. Options are: A: Do not notify the prospective client their solution is insecure and move on. B: Notify the client their solution is insecure even though they are not the code authors and can't fix it without contacting the vendor. C: Notify the vendor they have insecure code even though there is no financial incentive to do so - and likely violates terms and conditions for the client. D: Sell the exploit knowledge on some hacker forum... ( just kidding, this IS NOT really an option - toungue and cheek people... ). There are plenty of recent cases in the news where dudes hacking systems (usually without permission) but without nefarious/malicious intent, have been arrested and charged. For example, last months airline hack... http://thehackernews.com/2015/05/fbi-plane-hacking.html What'd Ya Think?
-
Assign your $criteria to a $_SESSION on initial load (the initial db pull). Then you only need to pass the page count (5, 10, 15, 20...) in the $_POST . session_start(); $_SESSION['criteria'] = $criteria; //assigned on initial results Then on your sub. query (BTW mysql_* is deprecated) which pulls the next five records, assign the "criteria" from the $_SESSION. if(isset($_SESSION['criteria']) && !empty($_SESSION['criteria'])) { //assign to local var if available $criteria = $_SESSION['criteria']; $sql="SELECT * FROM profiles WHERE Gender = $criteria['gender'] ORDER BY UserID DESC LIMIT 0 , $resultsPerPage"; } The Internet is "stateless" which requires your criteria to be stored in a container like a session, cookie or database in order to hold that current "criteria". hope that helps.
-
You'll want to set your PDOException parameter. $connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); Then it should report any errors correctly. What is your $connStatus reporting? Connected to database?
-
A lot of that work and more is available through Google Analytics. Rather than re inventing the wheel, I would take a look at how you integrate that solution into your web page. Generally, I'm all about "roll-your-own" but not in this.
-
Are you sure PHP has been enabled on your WAMP setup? Place this simple code in you website root directory. If it shows you all the PHP setting, then your PHP is working. <?php phpinfo(); phpinfo(INFO_MODULES); ?> Try that first.
-
Amazon is storing a cookie in you cookie jar. The cookie only contains the items you selected. To see their cookie in action, look under your browsers setting > Cookies. You can create, store and recall cookie data with PHP too. Have a look here http://php.net/manual/en/features.cookies.php. There are couple things to know. Don't store important information like User name or passwords. And make sure you set your cookies to destroy. /* next time they visit */ unset($_COOKIE["yourcookie"]); /* automatically on close (-1). */ setcookie("yourcookie","yourvalue",time()-1); Finally, cookies are not a sure thing. The web user can select to not accept your cookie in which case CroNix answer would be the better solution.
-
creating a Link to customers page using search
rwhite35 replied to moosey_man1988's topic in PHP Coding Help
You want to look at urlencoding( ) function and $_GET superglobals on php.net. The short answer is //concatinate all your vars proto prefix~custid $vars = $search_rs['prefix'] ."~". $search_rs['customerId']; //assign to $_GET <a href="editCustomer.php?customerRef=<?php echo $vars?>> Then on the editCustomer.php page if ($_GET['customerRef']) { $customer = explode('~',$_GET['customerRef']); } echo $customer[0]; //should be prefix echo $customer[1]; //should be custid -
depending on how your $_POST is organized - assuming its two dimensional and not a multi-dimensional array of array, you could use the following to process your input. $postArray = array(); foreach ($_POST as $key=>$value) { $postArray{$key} = filter_var($_POST[$key],FILTER_SANITIZE_FULL_SPECIAL_CHARS); //same as calling htmlspecialchars } This will create a array with sanitized values. Prototype would be something like Array ( [save_progress]=>value, [other_user]=>value, [save_application]=>value...)