Im coding in php and taking part in a coding competition which gives points to scripts on the basis of memory usage, running time, and ofcourse accuracy of algorighm.
I got the algo right and working for all test cases. But I got a little less marks than I expected.
To save lines of code, I used strpos() function in a loop.
when I changed strpos() function to manually finding string function that I made, my points increased...
Now I'm confused... I guess I can make more points if I use my own defined functions instead of all library functions I used (strlen,strpos,etc) ...
Does making our own defined functions in scripts help in making the code faster ?
I'm not a professional but have worked in php for 3-4 years and never thought of saving time/memory before :P so I'm kinda stuck over here...
In general, the built-in functions for basic things like string operations tend to be faster than anything you could code yourself.
According to TuxRadar, built-in PHP functions use
highly optimised C code that is likely
to be as fast as it can get.
so it's "never better to rewrite a built-in function using PHP".
Part of the performance issue of writing functions in PHP is that PHP code usually isn't compiled before running, it's interpreted. I think I read online somewhere a while back that some Facebook engineers actually wrote a PHP compiler or something though...but I could be wrong, I don't quite remember off the top of my head.
Related
I want to make some game in PHP that involves scripting. For obvious reasons I don't want players/users to use PHP that I just include or eval. So I decided to go with LUA.
But I've never experimented with LUA in PHP. So my questions are:
Is allowing user LUA script in (out of the box) PHP a secure solution?
If not, then can I (and how to) make it secure?
What I aim for:
User writes some code with some generic root function, let's say main()
PHP code calls that function and evaluates the results
LUA code should be able to call a select few methods on certain object. For example from class Enemy::isNear() or Enemy::getHP()
LUA code should not be able to call other methods/access other objects/call any global php functions/access any insecure OS stuff
Again, I only scratched LUA very long time ago for, where a game in C allowed for LUA mods. No experience with LUA in PHP at all.
If you are talking about this, the source code indicates it is just creating standard lua instance as with C embedding. It does not seem to define much of the lua-to-host interface whatsoever, so, lua code does not have direct access to the php state.
To have user call Enemy::isNear() you'll have to first put Enemy in the lua state first. It seems that it is capable of semi-intelligently convert php objects to lua tables (lua.c line 386), I'm not sure if method fields will transfer well. At worst you'll need to do implement object wrapping on your own (write a lua "class" whose constructor takes a php object and slaps a metatable on it). There seems to be a way of passing php functions to lua.
Lua should not have access to any php stuff you didn't put in. There are still dangerous lua functions: require, dofile, load, loadstring, loadfile and libraries os and debug in the lua's environment.
You can always check what is available to a lua function by putting in snippet like this:
for k in pairs(_ENV) do print(k) end
Just to be sure you might throw in this line as well:
if not (_G==_ENV) then for k in pairs(_G) do print(k) end end
From this point onwards proceed with lua manual on scoping and other discussions on sandboxing lua (e.g. this. Google finds other results as well). You might also read up on lua closures so that you don't accidentally stove undesirable methods in upvalues.
Finally, there are endless loops in the code while true do end. In case your sandbox does not take care of that (which is likely), you'll have to handle that externally. Probably like this.
I read an interesting quote on a Python forum that it's "easier to ask for forgiveness than it is to ask for permission". I'm not too familiar with the language so I can't say whether this is garbage. From working with .NET, it is my understanding that a try catch is an expensive operation and should be there for exception cases only. Kind of like a safety net.
Is there any merit to this type of behaviour with php? As in, is it quicker to read from a file inside a try catch vs checking to see if the file can be found / read before performing the read operation. I can see how it makes the code easier to maintain, but what are the perfoance implications. Is it more of a waste to check when 99.9% of the time the check is pointless.
To the best of my knowledge, this is not a standard practice in PHP. This is, in large part, because most PHP builtins threw PHP errors -- not exceptions! -- prior to PHP 7.0. PHP errors could not be caught by PHP try/catch blocks, making it mandatory to use explicit checks for functions that could fail.
If your code needs to be compatible with PHP 5.6 or earlier, you can't use this convention. It may be worth experimenting with if you can mandate PHP 7.0 or later for your code, but I don't know what implications this may have for performance.
Try and catch by itself is truly quite expensive. Even when it is not used (i.e. no exception is generated), there is still some overhead that is "embedded" into the generated assembly. As for simple check whether the file exists and can be accessed, same thing happens: both of the things are system calls that are generally even more expensive. You should, however, also consider that the read operation on a file is a system call as well.
Now the question is narrowed down to what is more expensive: 2 system calls or 1 syscall with the exception handling. My assumption here (which I am somewhat confident about) is that the latter will be more expensive in case where the exception is actually being thrown, but faster in other cases. Since you've indicated that there will, in most cases, be no problems with accessing the files, it may be the case that you "should" use the exceptions. It is easier to deal with errors and does make the code a little bit more pretty (although it is arguable).
A little bit more on the code side of things: it totally depends on what your framework looks like now and what you want it to look like. You can, in fact, create a class that will deal with all this stuff in any of the two ways and they both will look clean (if done properly) and easily maintainable. If, however, you don't feel like keeping it in a separate class (or a separate file\function\universe), I would go for the exception handling.
Finally, as said before, the exception handling will generally be faster in you case, but ask yourself a question: How much of a problem is it? Do you perform the operation once per page access or do you do it multiple times? Will the page be accessed often or just once a day? How much of an impact will this create compared to all the other pages\algorithms that you have. There is a good concept know as 90/10 rule: 90% of the code is executed 10% of the time and vice versa. If this particular code is in these 90%, you shouldn't even worry about the performance as your concern should be the other 10% of the code. (You can read more about this here)
And one more thing: as noted by duskwuff, whatever is written here holds for PHP version >= 7.0
I can't build hhvm at the moment for lack of access to a 64-bit VM, so I haven't been able to use the typechecker that they have. Their documentation doesn't seem to describe the operation of the typechecker (hh_server and hh_client?) in any detail.
What I'm wondering, for anyone who's used it, is if the typechecker could be used in this situation:
Let's say someone can't convert their PHP codebase to Hack, so they instead write their PHP with comments in the form of hacklang type annotations, and at build time use a tool to strip the comments out, make a hh file, run the typechecker and report errors.
E.g. original PHP:
<?php
function lar(/* int */ $x)/* : int */
{
return $x;
}
Make a copy of the above, strip out comments, change ?php to ?hh :
<?hh
function lar(int $x): int
{
return $x;
}
Run it through the typechecker and see if it produces errors.
That way you'd get access to legitimate type checking with normal PHP without the need for running it on HHVM. Does the typechecker run in a way amenable to this set up?
I am an engineer at Facebook who works on Hack. You definitely could do this and I wouldn't say it's a bad thing to do, but you'd be missing out on a bunch of great features. The Hack typechecker can be run at build time (hh_server --check /path/to/www), but the best way to run the typechecker is as a daemon. Since the daemon incrementally checks your code in the background, it can report the errors very quickly whenever asked. This allows you to get feedback while you are writing your code rather than after you have finished. This quick feedback loop really helps speed up development.
Some other things that you would be missing out on:
Many language features, like Collections, lambda expressions, runtime enforcement of type annotations, and trailing commas (Paul Tarjan's personal favorite)
HHVM's massive performance boost.
So if you absolutely can't use HHVM then this might be worth considering, but if you can then I strongly recommend HHVM in order to reap the full benefits of Hack.
This is exactly what we did in-house in our development division.
We made a script to convert code between hacklang and php as we wanted to be able to do the type checking without converting our production servers to hhvm (we are planing to do so)
You can find the script on my github page
https://gist.github.com/Chipcius/d3dd4052b07a152870bd#file-hacklang-php-juggler-php
You can convert you files by passing in a directory and a flag to decide the conversion level (decl, partial, strict)
After conversion you can run hh_client just as you were coding hacklang
When you want to turn back you can run the same script on your code with the php flag and it comments out the annotations that need commenting.
workflow example
php hacklang-php-juggler.php <myDir> hack
hh_client
php hacklang-php-juggler.php <myDir> php
I have a rather big php site, which was written for php4 and register_globals enabled. It is old custom CMS. Now I want to run it on the php5 hosting without register_globals. Is it possible to change parameters parsing from $id to $_GET["id"] automatically, with some script?
I can get parameters names from wget -r on this site.
It have dozens of php scripts, and it is not very easy to do this change manually.
PS: UPDATE: I want to convert only GET variables. The additional line is $var_name = $_GET["var_name"] for each parameter. This line should be inserted very high in the script, e.g. by adding a new <? ?> section at very top.
Running such tool would introduce great risk of introducing errors in code.
I'd suggest running extract() on superglobals, so that you force register_globals and aplication will work properly.
http://php.net/manual/pl/function.extract.php
Next, when everything will be ok, write an OO wrapper for input parameters, pack it into nice DI Container and start manually transitioning whole script to the new style.
I don't know of any tools that help you in the conversion, but you have several options:
Simulate register globals by doing the same thing that register_globals did: At the beginning of the script, put all variables from GET and POST into the global variable namespace (i.e. via extract). While this is fastest and the most easy solution, it will lead to the security problems that register_globals was known for, and it doesn't help with the performance of your application
Determine the variables that are used and load them only via the init script into $GLOBALS only. Still not nice
Determine the variables that are used and replace the GLOBALS usage with REQUEST
Walk through it manually. This way, you can be sure everything is correct and will have the least trouble afterwards.
From your description, solution 1 or 2 might be the best for you since the cms doesn't seem to be updated anyway (which is a shame).
Although the actual finding/replacing might take more time, doing this manually will most likely result in less bugs / weird behaviour.
If are not the original author of the application, then this manual finding/replacing is also an opportunity for you to become much more familiar with the codebase than some automatic method.
Automatic: fast, almost definitely will result in some horrible bugs
Manual: slower (likely), almost definitely will result in better understanding, less bugs - and any bugs that are introduced will be easier to fix because of your better understanding.
Is there any possibility to write php code to mysql and then use it in php, in order to process the output, not just write it?
I would like to use mysql, instead of included file...if it is possible.
You can use the eval() function to run a string as PHP code.
Store the string in the database and then get it from a query and run eval.
As everyone here will be saying, this isn't the best practice. There's a good chance that there is a better solution that you just haven't thought of yet. If there isn't, make sure the values in the database are not user editable of there could be some serious problems!
Alternatively, if you want to play it safer, you could define the PHP functions that can be called, and just store the function name. Then use call_user_func() to run the function!
This is much safer since you have explicitly defined the functions available to be run, but less flexible of course.
eval
Sure you can, you may use eval. But beware - eval is evil and if it contains user input a malicious user may take over your server. So, please, be kind, and don't use eval!
Yes you can store the PHP code like any other text and then use eval() to run it.
But: You won't get any warnings/errors if your code is wrong, only on runtime. This makes debugging your code extremely difficult.
So don't do it!
Really, I am serious about this. In the end, you will have a lot more work.
Besides that, without this database thing, your code is also easier to read and understand by others. They don't need to know what code is in the database, they can just look up the file that is included.
As others have answered, yes, that is possible; you can use eval() to run arbitrary PHP code. But it is rarely if ever a good idea to store PHP in the database and eval() it.
Perhaps you could outline what exactly you want to achieve and why you feel storing PHP in the database is a good solution. That way, if anyone feels he has a better solution for your problem, he can suggest it.
Sure it is possible and can be a good speed improvement. I'm using the cms "contenido" (www.contenido.org) where this practice is used for some editable components, (layouts/modules/data types etc.). Finally all code for one article is stored in one field and is performed with one eval call. Contenido is not perfect, nevertheless a good example for this practice.
Missing version control is a disadvantage. But it is not a real problem with a simple way to export and import the code fragments.
As everyone says it's a bad practice to store your code in database and use eval function. My personal reasons are:
I care about debugging (there are plugins for php that let you debug your php code. PHP debugger is integrated in PhpEd and I believe it is integrated in NetBeans too) and it would be more difficult with eval.
Performance issues:
The speed of eval Besides security
concerns eval also has the problem of
being incredibly slow. In my testing
on PHP 4.3.10 its 10 times slower then
normal code and 28 times slower on PHP
5.1 beta1.
(Source: http://blog.joshuaeichorn.com/archives/2005/08/01/using-eval-in-php/)
EDIT: Here are my results from testing script above on my machine (PHP 5.3.0):
Eval: 1000000 times took 8.2261250019073n
Same code not eval: 1000000 times took 0.27089691162109n
Eval in function: 1000000 times took 0.8873131275177n
So "evaled" code is 30.4 times slower than not evaled version of the same code.