开发者

What are the advantages/disadvantages of monolithic PHP coding versus small specialized php scripts?

I have historically used a monolithic approach to PHP coding.

That is, I write one index.php, with an average size of 70k-250k, and use

mod_rewrite

to turn the rest of the

REQUEST_URI 

into parameters passed into the index.php to control what is happening.

The alternative would be to write many small php scripts, each specialized to a particular purpose. I'm thinking that some of my more active ajax scripts may benefit from this.

One thing that has kept me in this thought process is I don't know how using includes, especially conditional includes would affect the performance of the opcode cache.

I have generally avoided includes altogether if possible due to my paranoia about this, but this results in either duplicating code, or staying monolithic.

As I'm using mod_rewrite anyway, converting between the two methodologies should be simple.

I开发者_如何学运维 look forward to your comments.

EDIT: One of my target apps currently handles 80-100 page hits per second (I got some decent hardware). Most of those are ajax requests. Everything works and is snappy, but I've developed as a php programmer without critique and need it.


Modular code is easier to understand and maintain. A huge monolithic codebase can become like a house of cards. It works just fine in practice, but changing any of the lower elements becomes impossible. If you split up your code into clear abstractions, it can be much easier to make changes and you'll save yourself a nightmare if you ever add developers.


The performance bonuses of not using included files is far outweighed by the ease of maintaining and debugging a large application using included files.

Rework is waste. Copying and pasting code from one app to another is maintenance hell.


In addition to the other comments (with which I agree completely), another view: I have made the experience that a monolithic approach, if driven to extremes, costs valuable RAM - the whole file has to be loaded to be interpreted, no matter whether everything from it is needed or not, and that alone eats off a lot from the 8, 16, or 32 MB you get per instance.


Please don't forget about testing and maintaining the code. I can't image if you're able to write unit-tests to a project which is just in single file. Futher more, it's much harded to predict which functionality can be broken by changes you've just made. In case of modular architecture if you change some module then you can only break this module and modules which depends on it. Even a small changes can be fatal to single file projects (you can forget to close quote which will break all pages at once). I think you must retest all the functionality after even small changes we've made. And this can be a pain for testers ecpecialy you're not able to use unit-tests.

Also if all code i stored in a single file then you'll more likely have a bad code. Such code will tend you to use global variables. In this case it's hard to reuse such code in other project. Of cause you can copy it, but remember when you copy something you copy all its bugs. Just imagane the project where you can use set of well-tested (tell thanks to unit-tests) libraries. When new bug appear then it's just fixed in a single place.

One more thing, when you're working in a team using a single file will be pain. Even if there is only 2 developers they waste much time to merge changes.

Any way, if your project is not big at all you can use single file appoch.


For Unix command line scripting, the monolithic approach allow a very high level of portability.

Using a single (hashbang) script even allow to dump the script in usr/bin

sudo cp myprog /usr/bin
/* (...) */
sudo cp myprog /usr/games
/* (...) */

This allow to call the program from anywhere, any path, by just typing myprog, instead of /PATH/./myprog. Make sure it can be trusted!

We have to take an extra care of the paths.


Some simple examples about paths:

/* Create a folder in the home directory, named as the script name, if not existing. -*/
if (!is_dir($_SERVER["HOME"]."/".$_SERVER["SCRIPT_NAME"])){
  @mkdir($_SERVER["HOME"]."/".$_SERVER["SCRIPT_NAME"]);
}

/* Program folder path: --------------------------------------------------------------*/
$PATH = $_SERVER["HOME"]."/".basename($_SERVER["SCRIPT_NAME"])."/";

/* Program running path, currently: --------------------------------------------------------------*/
$JOBPATH = getcwd();

Handle POSIX SIGNALS

/* Register cleaning actions at SIGINT ------------------------------------- */
function shutdown() {
  // Perform actions at ctrl+c 
  echo "Good bye!";
  exit;
}
/* Register resize at SIGWINCH ---------------------------------------------- */
function consoleResize() {
  @ob_start;
  $W = (int)exec("tput cols");   // Columns count
  $H = (int)exec("tput lines");  // Lines count
  @ob_end_clean();
  // Shell window terminal resized!
}

/* Register action at SIGSTOP (Ctrl + z) ---------------------------------------------- */
function sigSTOP() {
  // Program paused!
}

/* Register action at SIGCONT (Type fg to resume) ---------------------------------------------- */
function sigCONT() {
  // Program restarted!
}

register_shutdown_function("shutdown");
declare(ticks = 1);
pcntl_signal(SIGINT, "shutdown");
pcntl_signal(SIGWINCH, "consoleResize");

This doesn't mean we have to write everything in one block, but merge the rendering in one file allow many extra capabilities in a unix env.

There is a lot to say, php as cli script is an amazing beast.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜