Related
I'm writing some classes for a personal project that handles data and ensures it conforms to my exact specifications. The output is an array (JSON object for API) consisting of true\false values for the respective fields to see if they passed my tests.
Some of the tests are complex with multiple conditions and it is hard determine at face value why a field failed the tests.
For each of the tests I was thinking of putting a DEBUG flag which can be enabled at object instantiation. That leaves me with two choices.
A) Copy the validate function as follows. Within the debug_validate() function I return an additional array with the fields and the reason they failed. This requires me to maintain two copies of the function.
if ($this->debug_mode) {
debug_validate();
}else{
validate();
}
B) Within the actual validate function I can do the following
if (!test1($field)) {
$validation_result[$field]=false;
if($this->debug_mode) {
$debug_result[$field]="Field is too small. Result of strlen: ".strlen($field);
}
}
.
.
.
This means that I have to run the "if" blocks every time the validation function runs even though it will not be used 99.9999999% of the time. It seems inefficient.
Am I overthinking this. I mean with modern hardware who cares if it runs an extra if statement. I just wonder if in production this actually matters when it comes to millions of requests (have to think big :)) and these debug statements start to add up (few MS here, few MS there)
Well if you were writing this for a company, then yes it would be a bad practice. The team would kick back the code to you during a code review & have you remove the debugging code.
Since you're developing a personal project, then you can use debugging code for now. The benefit is that it will help you debug the project faster, than without it. You can clean the code up later on, when you bake it for it's final production release. Or if you're switching from a beta to gold status in a future release (say 6 months or 1 year from now).
The hard part is seeing what's going on with a server, where you don't have direct access to the source code. That's usually what occurs on a QA, test, staging or production server. You can easily edit the code on your localhost box, but you won't be able to easily edit it on those other servers.
What you don't want to do is leave this open, without writing a way to securely protect it. You don't want others to be able to trigger this code... if ($this->debug_mode) {. If you put something important inside of that PHP block... like SQL... then someone can see it & start to understand how your database is laid out. It'll give them a clue as to where to go, to start hacking into your database. They'll want to start elevating their user access privileges! You don't want them to make themselves an administrator & lock you out of your own database! So make sure that you secure your code with something like this:
if (($_SERVER['HTTP_HOST'] === 'qa.yoursite.com') && ($this->debug_mode)) {
debug_validate(); // <- QA uses this.
} else {
validate(); // <- Production uses this.
}
Note: That only runs on a QA server, but it runs for everyone who can use that server! So be careful that you don't give access to the QA server to anyone else but yourself!
If you have a password protected login with a userId, then you can use this example. It will work on any server. You can also combine these 2 code examples to lock a userId to a specific server.
if ($myUserId === 'myUserId') {
debug_validate(); // <- You'll use this.
} else {
validate(); // <- Everyone else uses this.
}
Ideally, what you want to do is to only use the validate(); code without the debug_validate(); code and setup a unit test to run against your code. It should include tests to verify that everything validates correctly. It should also include tests to verify that bad data won't validate. When your site gets to that level, then you won't need to use the debug_validate() method anymore. The unit tests will report if everything is good or if anything fails.
I wouldn't worry about the ms load time at this point. Nor the server load. The PHP code will run so fast that you won't notice it. Focus more on getting the code to work properly, than making it look pretty. You can always refactor the code later to clean it up once it's working. It'll make you feel happier when you see the working code getting cleaner!
Your production code would have to evaluate an extra "IF" conditional in either case, unless I am misunderstanding? Whether it lies within the function, or within the calling script, the additional overhead (which will likely be extremely minimal even under load, unless you have thousands of them) would be the same either way.
I have had production code with "Debug Mode" type flags in the past and it has worked fine - however, there are some problems with that approach - namely, you need to change code (i.e. toggle the flag on or off) and therefore do another build / deployment in order to debug. Also, remembering to turn on / off debug mode can be a chore. And it tends to dirty up your code / make it less readable / easily maintainable.
Personally, I would take a little bit different approach, especially if you think debugging will be a common thing for your app - You could write separate unit tests to do debugging, using a tool like PHP Unit. If you are logging incoming requests to your application in some shape or form, it should be easy to pipe production data over to your unit test code base and conduct your debugging in that environment, instead of in your production code.
If you are running a test driven development environment, writing unit tests first should be common practice anyway.
First of all, I don't know if it is called Unit Testing. If it has a different name, feel free to correct me.
I'm currently developing web applications like this.
Let's say I'm developing a form to save values into database. I develop HTML and PHP. I time to time press F5 in Browser and check if HTML/jQuery has no bugs and PHP doesn't give errors like missed semicolon.
When it is complete and everything is ready to be tested, I start testing small pieces of my code. Like;
-Do $_POST array correctly obtains values from form file? (I test with print_r)
-Is "$email" variable correctly sanitized to be a valid e-mail? (I test it with different posibilities, eg: aaa#bbb, aa#bb.com, a##b.net etc.)
-Is the form submitted passed all controls, and successfully inserted to the database? (I check my MySQL table.)
-Does the form shows error/success messages correctly?
-...etc.
If it works with correct values, and fails with wrong values; I believe the form is working as intended and there is no bugs, so I move onto other things.
Instead of doing this, I want to ensure things works perfectly, otherwise notifies me about the problem without spamming F5 on browser.
Like this;
<?php
/* Unit Testing Start --
-ensure: isset($_POST['submit']) returns TRUE;
-ensure: isset($email) returns TRUE;
-ensure: isValidEmail($email) returns TRUE;
-ensure: connectDatabase() returns TRUE;
-ensure: getMysqlAffectedRows() returns 1;
-ensure: hasErrors() returns false;
*/
?>
My form codes, uses the functions I posted above.
When it runs, it should show me a message like this: (preferably logging it also)
Test complete. Tested (6) possibilities, (4) succeeded, (2) failed.
Failed 1: isValidEmail() returned FALSE, expected: TRUE.
Failed 2: getMysqlAffectedRows returned NULL/0, expected INTEGER 1.
Something like this would save me alot of time and make it easier to maintain my codes.
I do NOT want to do this:
$email = 'xxx#yyy.com';
echo isValidEmail($email) ? 'true' : 'false';
Then I have to erase those lines from my PHP scripts. Tests has to stay there forever, unless I manually delete them. They should be like comments so in production website, they won't be executed. However, in my development PC, I'll install whatever I need to install and those comments has to be parsed/logged.
So, yeah. That's all. Now onto the questions:
Is it something possible to do with PHP? If so, how can I do this?
What is it called, Unit Testing, or what?
How do you guys test whatever you develop?
How do you guys manage to develop huge web applications without worrying; "If I change this function, the entire website may break."? Also, how are you being sure changing function didn't break anything? X page may work fine but Y may be broken because of something you didn't think before. Like, division by 3 on X page may work fine, but division by 0 on Y page will definitely give errors, but you only checked X page?
I'll really be glad if you can reply to my questions and help me be a better developer.
Thanks!
Yes, automated testing is a cornerstone of solid software development, precisely because it's impossible to keep checking everything manually by clicking in the browser. Unit tests are typically "technical" tests that make sure a specific "unit" (typically a function or class) returns expected return values for a specified input. Functional testing tests larger units of code for correct behavior. Acceptance testing tests the final application from the point of view of a user.
There are a number of frameworks and tools to cover these different needs:
PHPUnit - the de facto unit testing framework for PHP
Behat - a testing framework focussing on offering "business readable" tests
Codeception - a framework trying to be both readable and technical
All of the above have excellent documentation which ease you into the thinking of working with unit tests. I recommend you start by reading into PHPUnit, then look at what Behat or Codeception can offer you.
As general advice: Test whether your code behaves correctly. Do not test "what is does", test whether you get the result you expect when you do something. For example, don't test isset($_POST['submit']). That's too detailed, there's no point in covering every single line of your application with a test. Instead, test larger units of code. Test that when you submit a form with known given values that your code correctly redirects you to the next page. Or test that your authentication system correctly denies access to unprivileged users. You want tests to read like this:
Scenario: Login
Given I am on the login page
When I log in as user "Jon" with the password "foo"
Then I should be logged in
Or:
Scenario: Deny unprivileged user
Given I am logged in as the user "Jon" with access level 1
When I try to access the action "restricted"
Then I should be denied access
Not:
Scenario: Login
Given I submit a form with the values "Jon" as username and "foo" as password
When I check the $_POST array I should see "Jon" in the key "name" and ...
...
The above can literally be tests in Behat by the way.
To make sure these tests you wrote are actually worth something, you need to run them on a regular basis. Maybe you create a trigger in your version control system to run your test suite automatically when code is checked in and deny checkins which fail tests. Best though is if you have a Continuous Integration server set up which regularly gets the latest code from your repository and runs the tests on it. If you set this up properly, you'll automatically be notified about all sorts of edge problems that easily go overlooked during regular development. For instance, the CI server should try to set up and run the application from scratch every time and may alert you that there's a problem getting a dependency from a third party you depend on, or that there's a problem in your database migration scripts. Things you wouldn't have noticed otherwise, since you don't always fetch dependencies and don't always re-run your migration scripts.
In the end you're aiming for having your code "exercised" automatically on a continual basis from all possible angles. That's the only way to find problems with it.
For CI software, personally I like TeamCity a lot, but Jenkins and Hudson are very popular and there are a ton of other CI tools.
Acording to WikiPedia:
In computer programming, unit testing is a method by which individual
units of source code, sets of one or more computer program modules
together with associated control data, usage procedures, and operating
procedures, are tested to determine if they are fit for use.
I'm guessing this what you are doing can be called UnitTesting.
The best way to UnitTest is though a well know framework. There are few for PHP. I guess the most popular is PHPUnit. Appart from testing it does other cool things like code coverage report (I'm sure other frameworks do it as well).
I work on Eclipse and I have PHPUnit integrated with my IDE. While developing I don't have to switch between windows. I just run a test and see does my code work or not. It saves lots of time.
It sounds like you should check out the simpletest.
I have a PHP code stored in the database, I need to execute it when retrieved.
But my code is a mix of HTML and PHP, mainly used in echo "";
A sample that looks like my code:
echo "Some Text " . $var['something'] . " more text " . $anotherVar['something2'];
How can I execute a code like the either if I add the data to the DB with echo""; or without it.
Any ideas?
UPDATE:
I forgot to mention, I'm using this on a website that will be used on intranet and security will be enforced on the server to ensure data safety.
I have a PHP code stored in the database
STOP now.
Move the code out of the database.
And never mix your code with data again.
It's not only a bad idea but also invitation to several type of hacking attempts.
You can do with eval(). but never use it . The eval() is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to pass any user provided data into it without properly validating it beforehand.
See eval. It lets you pass a string containing PHP and run it as if you'd written it directly into your file.
It's not a common practice to store executable PHP in a database; is the code you store really that different that it makes more sense to maintain many copies of it rather than adapting it to do the same thing to static data in the database? The use of eval is often considered bad practice as it can lead to problems with maintenance, if there's a way of avoiding it, it's normally worth it.
You can execute code with eval():
$code_str = "echo 'Im executed'";
eval($code_str );
BUT PAY ATTENTION that this is not safe: if someone will get access on your database he will be able to execute any code on your server
use the eval() function.
heres some info
http://www.php.net/manual/en/function.eval.php
something along the lines of:
eval($yourcode);
If that is the last resort, you want it to be secure as it will evaluate anything and hackers love that. Look into Suhosin or other paths to secure this in production.
As everyone'd indicated using eval() is a bad approach for your need. But you can have almost the same result by using whitelist approach.
Make a php file , db_driven_functions.php for instance. get your data from db. and map them in an array as below
//$sql_fn_parameters[0] = function name
//$sql_fn_parameters[1,2,3.....] = function parameters
Then define functions those include your php code blocks.for instance
my_echo($sql_fn_parameters){
echo $sql_fn_parameters[1];//numbered or assoc..
}
then pull the data which contains function name
after controlling if that function is defined
function_exists("$sql_fn_parameters[0]")
call function
call_user_func_array() or call_user_func()
( any you may also filter parameters array $sql_sourced_parameters_array does not contain any risky syntaxes for more security.)
And have your code controlled from db without a risk.
seems a little bit long way but after implementing it's really a joy to use an admin panel driven php flow.
BUT building a structure like this with OOP is better in long term. (Autoloading of classes etc. )
Eval is not safe obviously.
The best route IMO
Save your data in a table
Run a stored procedure when you are ready to grab and process that data
You should not abuse the database this way. And in general, dynamic code execution is a bad idea. You could employ a more elegant solution to this problem using template engines like Smarty or XSLT.
There are a few way to achieve this:
1) By using evil
eval($data);
That's not a typo, eval is usually considered evil and for good reasons. If you think you have fully validated user data to safely use eval, you are likely wrong, and have given a hacker full access to your system. Even if you only use eval for your own data, hacking the database is now enough to gain full access to everything else. It's also a nightmare to debug code used in eval.
2) Save the data to a file, then include it
file_put_contents($path, $data); include $path;
There are still the same security concerns as eval but at least this time the code is easier to debug. You can even test the code before executing it, eg:
if (strpos(exec('php -l '.$path), 'No syntax errors detected') === false))
{
include $path;
}
The downside to this method, is the extra overhead involved in saving the code.
3) Execute the code straight from the database.
You'd need to use database software that allows this. As far as I am aware, this is only includes database software that stores the content as text files. Having database software with "php eval" built in would not be a good thing. You could try txt-db-api. Alternatively, you could write your own. It would like become very difficult to maintain if you do though but is something to consider if you know exactly how you want your data to be structured and are unlikely to change your mind later.
This could save a lot of overhead and have many speed benefits. It likely won't though. Many types of queries run way faster using a traditional database because they are specifically designed for that purpose. If there's a possibility of trying to write to a file more than once at the same time, then you have to create a locking method to handle that.
4) Store php code as text files outside of the database
If your database contains a lot of data that isn't php code, why even store the php code in the database? This could save a lot of overhead, and if you're database is hacked, then it may no longer be enough to gain full access to your system.
Some of the security considerations
Probably more than 99% of the time, you shouldn't even be attempting to do what you are doing. Maybe you have found an exception though, but just being an intranet, isn't enough, and certainly doesn't mean it's safe to ignore security practices. Unless everyone on the intranet needs full admin access, they shouldn't be able to get it. It's best for everyone to have the minimum privileges necessary. If one machine does get hacked, you don't want the hacker to have easy access to everything on the entire intranet. It's likely the hacker will hide what they are doing and will introduce exploits to later bypass your server security.
I certainly need to do this for the CMS I am developing. I'm designing it mainly to produce dynamic content, not static content. The data itself is mostly code. I started off with simple text files, however it slowly evolved into a complicated text file database. It's very fast and efficient, as the only queries I need are very simply and use indexing. I am now focusing on hiding the complexity from myself and making it easy to maintain with greater automation. Directly writing php code or performing admin tasks requires a separate environment with Superuser access for only myself. This is only out of necessity though, as I manage my server from within, and I have produced my own debugging tools and made an environment for code structured a specific way that hides complexity. Using a traditional code editor, then uploading via ssh would now be too complicated to be efficient. Clients will only be able to write php code indirectly though and I have to go to extreme lengths to make that possible, just to avoid the obvious security risks. There are not so obvious ones too. I've had to create an entire framework called Jhp and every piece of code, is then parsed into php. Every function has to pass a whitelist, is renamed or throws an error, and every variable is renamed, and more. Without writing my own parser and with just a simple blacklist, it would never be even a tiny bit secure. Nothing whatsoever client-side can be trusted, unless I can confirm on every request that it has come entirely from myself, and even then my code error checks before saving so I don't accidentally break my system, and just in case I still do, I have another identical environment to fix it with, and detailed error information in the console that even works for fatal errors, whilst always been hidden from the public.
Conclusion
Unless you go to the same lengths I have (at minimum), then you will probably just get hacked. If you are sure that it is worth going to those lengths, then maybe you have found an exception. If your aim is to produce code with code, then the data is always going to be code and it cannot be separated. Just remember, there are a lot more security considerations other than what I have put in this answer and unless the entire purpose of what you are doing makes this a necessity, then why bother at all mix data with code?
Ok I get a script from: http://abeautifulsite.net/blog/2008/03/jquery-file-tree/
Its a directory listing script. I am having troubles with it. It works out of the box no problems per say other than the put fact that it goes way back into the system structure then I am allowed to even see some how.
The person that made the script has this one line that throws me off and I can't make heads of tales of it per say.
file_exists($root . $_POST['dir'])
I've never seen $root in that context before. Nor is it defined anywhere in the script from what I can tell. So is that a valid thing? If not can anyone tell me how I can use this script beneficially to just displaying directories starting at a specific directory. The document I point to with the above link shows an example, but it doesn't seem to mean anything to the scripts workings.
On the other hand if someone knows of a canned script thats very similar in nature I'd be happy to give that a look too. But I'd really like to edit this one to work the way I want it to work so any help would be appreciated.
an example of how far its going back can be found at http://domainsvault.com/tree/
I say its going far back because I don't even have access to those directories through my ftp.. its a shared system.. hostgator..
*EDIT* Thanks Everyone for the input, this essentially what I was afraid of hearing. It was hopped that we could skip reinventing the wheel by using this concept. But its appearing more so than not that its basically a bricked concept and far from worth using and attempting to tamper with. It'd likely be a lot more easy for me to build something from scratch than have to deal with this. This was just one of those canned scripts you find it looks ascetically pleasing to the eye, and you hope for the best. Didn't turn out to be the case, thanks again all.
file_exists($root . $_POST['dir'])
Run away.
This connector script does no checking on what paths you pass to it, so it's perfectly possible to escape the root (which, yes, you're supposed to set manually) and browse any files on your server that the web user has access to.
Also, it fails to do URL-escaping, and mangles Unicode through inadvisable use of htmlentities. This will make files with various punctuation or non-ASCII characters in fail.
This is a shonky and insecure script. Do not deploy it.
$root is a user-defined variable. It should be defined somewhere in the script - it may be a global. The script can still work if the variable doesn't exist (it might have been deleted in a previous code refactor), in that case you should just delete the variable from the line you copied here.
I think $root means $_SERVER[ 'DOCUMENT_ROOT']
you can defined as
$root=$_SERVER[ 'DOCUMENT_ROOT']
at the beginning
I'm trying to write a page that calls PHP that's stored in a MySQL database. The page that is stored in the MySQL database contains PHP (and HTML) code which I want to run on page load.
How could I go about doing this?
You can use the eval command for this. I would recommend against this though, because there's a lot of pitfalls using this approach. Debugging is hard(er), it implies some security risks (bad content in the DB gets executed, uh oh).
See When is eval evil in php? for instance. Google for Eval is Evil, and you'll find a lot of examples why you should find another solution.
Addition: Another good article with some references to exploits is this blogpost. Refers to past vBulletin and phpMyAdmin exploits which were caused by improper Eval usage.
Easy:
$x // your variable with the data from the DB
<?php echo eval("?>".$x."<?") ?>
Let me know, works great for me in MANY applications, can't help but notice that everyone is quick to say how bad it is, but slow to actually help out with a straight answer...
eval() function was covered in other responses here. I agree you should limit use of eval unless it is absolutely needed. Instead of having PHP code in db you could have just a class name that has method called, say, execute(). Whenever you need to run your custom PHP code just instantiate the class of name you just fetched from db and run ->execute() on it. It is much cleaner solution and gives you great field of flexibility and improves site security significantly.
You can look at the eval function in PHP. It allows you to run arbitrary PHP code. It can be a huge security risk, though, and is best avoided.
Have you considered using your Source Control system to store different forks for the various installations (and the modules that differ among them)? That would be one of several best practices for application configuration I can think of. Yours is not an unusual requirement, so it's a problem that's been solved by others in the past; and storing code in a database is one I think you'd have a hard time finding reference to, or being advised as a best practice.
Good thing you posted the clarification. You've probably unintentionally posed an answer in search of a suitable question.
Read php code from database and save to file with unique name and then include file
this easy way for run php code and debug it.
$uniqid="tmp/".date("d-m-Y h-i-s").'_'.$Title."_".uniqid().".php";
$file = fopen($uniqid,"w");
fwrite($file,"<?php \r\n ".$R['Body']);
fclose($file);
// eval($R['Body']);
include $uniqid;
How I did this is to have a field in the database that identified something unique about the block of code needing to be executed. That one word is in the file name of that code. I put the strings together to point to the php file to be included. example:
$lookFor = $row['page'];
include("resources/" . $lookFor . "Codebase.php");
In this way even if a hacker could access you DB he couldn't put malicious code straight in there to be executed. He could perhaps change the reference word, but unless he could actually put a file directly onto the server it would do him no good. If he could put files directly onto the server, you're sunk then anyway if he really wants to be nasty. Just my two cents worth.
And yes, there are reasons you would want to execute stored code, but there are cons.