I've written small command line scripts in PHP before (without any helper libraries). Using PHP for such things is nice when interfacing with web services (JSON parsing, SimpleXML, etc).
Perhaps Peachpie, when it reaches production quality, will also help with that, as then calling .NET (and maybe, through that, WinRT) APIs from PHP code will be made easier.
For the same reason a lot of people says that the use node as backend. Because they must use javascript in the frontend they use it in the backend. If one is using php as a language for a project and that project has related commands and with php your are capable of doing, why not?
php-cli scripts normally don't have an execution time limit (or a memory limit?), which makes them ideal for upgrades/database maintenance/cron jobs/etc while being able to reuse code from the application itself
> php-cli scripts normally don't have an execution time limit (or a memory limit?), which makes them ideal for upgrades/database maintenance/cron jobs/etc while being able to reuse code from the application itself
?
PHP enforces memory limits out of the box by default. What languages have execution limits on CLI?
They're probably referring to web hosts. Many hosts have timeouts for the web, but not the cli. So for long running tasks you write cli scripts. In the WordPress world this is easily done using WPCli and eval-file.
I've written a handful of apps using PHP-gtk (all written more than ten years ago). I'm sure it's improved since then, but I'd still say it's not worth the effort.
There are plenty of companies that rely on PHP that also have to work with CLI. I believe they are better informed when it comes to making decisions between handling CLI via an entirely different language and sticking to PHP.
It is fine, especially if you want cli tool that can do http, database connections, etc. without any external deps or other PHP code and want it quickly.
While comments can be flagged and/or downvoted, submissions can only be flagged. There's a karma threshold to flag submissions—offhand I don't recall what it is.
I routinely use vanilla PHP (no special libraries) for CLI scripts. It's actually fantastic for this. It has a large set of functions that do everything you want, no imports required, and it has C-like syntax with real types and functions.
It's a similar experience. PHP is slightly more Perl-ish (dollar signs, no namespaces for built-in functions, `or die`, native string interpolation) and has type declarations.
I know Perl, C, C++ and PHP quite well, but I'd never, ever call C-like syntax a plus.
It's astonishing how feeble modern PHP is, that to comapre strings you often have to use strcmp. In 2017. It's like all the cruft of ANSI C with a whole bunch of $ characters spiked in.
It's the most common syntax pattern of popular languages. Statistically, more developers know a language with a "C-like" syntax than Lisp, Haskell, Erlang..
C-style syntax is fairly popular [1]. If it had lisp syntax or haskell syntax most people would complain that they can't figure out what's going on without learning all that syntax.
>that to comapre strings you often have to use strcmp
For equality === works just fine. For < and > there is no one obviously correct order, so it's entirely reasonable to use functions for that.
I totally agree. I find PHP CLI scripts to have a good balance between functionality, simplicity and performance. It's definitely not suited for every task, but I do think it's great for most tasks.
> I routinely use vanilla PHP (no special libraries) for CLI scripts
Vanilla PHP has better argument parsing than many recent hipster language. Go has some sort of ugly non conventional argument library which is barely usable, Node has none. But nothing beats vanilla Python for that tasks IMHO.
I haven't used PHP for CLI scripting, however I've used Python and Golang. I can say that Golang argument library (flag) feels more straightforward to me than Python's argparse.
import "flag"
var ip = flag.Int("flagname", 1234, "help message for flagname")
...
// flag.Parse() once in the main function
vs
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help="display a square of a given number",
type=int)
...
args = parser.parse_args()
In the Go example you get a pointer just like in C, in the python example you get a special object and can access its fields. Both are simple, but Golang is IMHO closer to C in this matter.
This is not argument parsing. I'm pretty sure Node doesn't even do anything, it just gets an array of strings from the CLI, argv C style isn't getting options prefixed with - or -- directly from the CLI, and putting them in a map or something. So no, node has no facility in its standard library for that. Node is not known for its extensive standard library in anyway.
My first intention was to extend Symfony/Console and make it more easy to use, but the main pain points were defining and parsing command line args, mocking stdin and filesystem, ...
Batteries are nice, but it's handy to have a breadboard and some wiring. For a super-simple CLI script without interaction, plain PHP's fine, but if you're making something interactive that's prompting, using color codes, logging, etc., a framework's pretty handy - especially if it's for a larger app that's got models and services to interact with.
One of the things I've hated about maintaining PHP web apps is how reliant on the web interface they usually are; this has thankfully started to change. Drupal (finally) has decent CLI tools. MediaWiki is among the few to have had CLI tools for many years.
But, the thing that struck me about this project and the examples is just how verbose PHP has gotten over the years. It is strikingly similar to old Java, in terms of class definitions and the like. I know PHP has also gotten faster and lot of "grown up" language features in that time, too, but some of its charm as a language with strong "whipuptitude" is lost. I'm certain it's a better language than it was a decade or two ago, and it was, frankly, awful by many measures back then. But, it sure does take a lot of typing.
So, I like that things like this exist (though I likely wouldn't use it...I really need most of my CLI tools to be standalone with no non-core dependencies). I'd like it if every web developer knew how to make good CLI apps and did so for every web app. I use Perl or POSIX shell mostly for my CLI apps, but PHP makes perfect sense for tools that work with existing web apps (the Drupal helper scripts I've written are mostly in PHP).
drush is great, and I've been using it for a few years. But, module support in drush was abysmal until pretty recently, though (still pretty weak; I'd guess 80-90% of modules have no drush support). And, for a lot of core Drupal stuff that I would think would be obvious (CRUD for arbitrary entities, for example) one has to write one's own drush plugin, and it's often complicated as hell. I love what drush does, but I've frequently been disappointed/frustrated by what it doesn't.
That's not to denigrate drush or the developer(s) of drush. drush is/was a remarkable improvement over the pre-drush era. I just think Drupal wasn't built to be driven by a CLI. It isn't API-native, by any stretch of the imagination, nor is it front-end agnostic. So, drush is historically working around rather than working with, and it shows in that most of Drupal is still inaccessible to drush (at least in Drupal 7; I haven't deployed Drupal 8 and probably never will as the migration from 6 to 7 was too painful for me to be willing to ever do it again).
So...I think we may just disagree on what "decent" and "finally" means. Also, compare to some other ways to build web apps; most modern web frameworks have pretty obvious ways to build CLI tools, and often are built around standard frameworks for doing so (Yeoman or generators/console in Rails). Drupal being based on Symfony now gets it a lot of that same kind of thing; so, it is recently decent, by my estimation. Others may disagree, of course.
I feel that way about D7. If D8 is worse, I definitely don't want to go down the rabbit hole even a little bit.
I feel like Drupal could be a workshop on why "a wrong abstraction is worse than no abstraction". I'd assumed things were better on that front in D8, based on what I'd read, and based on the theory that at least the wrong abstractions would be common across everything (Drupal has always had the problem of a dozen different modules for every trivial thing, and every module needs a different combination of those trivial thing modules). I'd hope, at least, that database abstractions are nicer? The database API in Drupal 7 is, frankly, awful.
> The database API in Drupal 7 is, frankly, awful.
While Larry Garfield architected it, yours truly here put in quite some work implementing the API you like so much :) But that's just context -- I could ask you what are your problems but I won't, I am out and the API is frozen until D9. I would recommend filing an issue to tell what you don't like.
Sorry to be harsh, and I guess my problem is really at a higher level, now that I'm looking at the code again. It's the entities and fields and a bunch of other higher level APIs that interact with the database that I hate. But, that's the way everything interacts with the database in D7. So, I'm wrong about the database API...it's just that working with data in D7 doesn't use the database API directly anymore, it uses entities and other higher-level APIs.
My problem is that by the time something reaches the database is it completely unrecognizable and is spewed all over the database in a half dozen tables. This is a problem of D7 much more than D6. It takes a handful of queries to build an "entity", for instance, and forget hitting the database from outside of Drupal.
Every CMS we've used in the past, I was able to use the database as the source of truth across many apps in many languages; the database was effectively the API I used to share data across our Perl and Python apps and Drupal. With Drupal 7 I can't do that at all. I have to go through Drupal to pull anything out or put anything into the database in a way that Drupal can work with it. It's just a pain in the ass. And, Drupal 7 is an awful experience for building APIs, so I can't really integrate stuff that way, either. I understand improving the API building experience is a focus for D8.
Anyway, I want my database to look like my model, and Drupal 7 doesn't do that. It spreads the model across a whole bunch of tables (I've got like 60 "drupal_field" tables in my D7 database...I have no idea what to do with all that mess). And, the APIs in Drupal to work with entities and fields and such are really ornery to work with and getting useful errors out of them is impossible. That's not the fault of the low-level database API, but it is the fault of how Drupal 7 implements putting things into the database. If that makes sense.
Mostly I've just realized Drupal doesn't fit my mental model of how CRUD apps should work, and working with it has been a real chore. I know lots of people are super productive with it, but in several years of poking at it in my spare time, I still don't "get it". I honestly still don't even have a good mental model for how the pieces fit together; it's so big, there are so many competing ways to do anything, it's full of re-implementations from one version to the next, etc. I can't make any sense out of it, and every time I come back to it it takes me hours just to get up to speed enough to make minor changes.
> Drupal being based on Symfony now gets it a lot of that same kind of thing; so, it is recently decent, by my estimation. Others may disagree, of course.
Like me. As far as I can see, while Symfony might be a decent framework but the integration between Drupal and Symfony is atrocious because it's an incredibly bad fit as the two systems had fundamentally different philosophies, mostly in the explicit vs implicit department. Compare a Drupal hook implementation to a Symfony event subscriber and you will see.
And I must be missing something what Symfony Console apps bring to the table compared to the absolutely trivial drush implementations... But each to their own, I guess.
> But, the thing that struck me about this project and the examples is just how verbose PHP has gotten over the years. It is strikingly similar to old Java, in terms of class definitions and the like.
It's all opt-in. Nothing forces you to use Composer, classes or even type hinting in PHP if you do not depend on third party libraries backed by composer. Most of C extensions from 10 years ago are still here and procedural code from that era would probably still work today on PHP 7.
JavaScript has gotten extremely concise in recent years, even with type annotations (with TypeScript or Flow). Perl with Moose/Moo is very concise. I dunno about Ruby or Python in terms of type annotations, but both have more concise class definition syntax. So, kinda all of the direct competitors to PHP have a more concise syntax for the same features.
But, maybe more importantly, this seems to be using classes where it makes little sense to use classes, but I see it a lot in PHP code. An idiomatic implementation of the same kinds of tools in JS/Perl/Python/Ruby might be shorter simply by virtue of not wrapping everything in a class. It's sort of an anti-pattern to OOP-all-the-things in those languages, while in PHP there seems to be a religious zeal for classes.
And yet nearly everybody does. Is there a compelling upside to justify that tradeoff? I can't think of a worse fate for a language than trying to mimic Java circa 1998, but that's exactly what's happening.
> But, the thing that struck me about this project and the examples is just how verbose PHP has gotten over the years. It is strikingly similar to old Java, in terms of class definitions and the like.
Something that probably hurts the language here is the lack of autoloading for functions, whereas it exists for classes, so exposing bare functions is a runtime performance penalty (their containing files must be loaded on every request, if you use Composer), which results in a preference for putting everything in a class. :/
Ah, that explains it. I didn't know about that, but my first thought was, "Why the hell is every single thing wrapped in a class?" That'd be considered non-idiomatic in JS/Perl/Python/Ruby, I think. Maybe not Ruby; Rubyists like their classes.
PHP is not really a good candidate for something meant to be distributed to other platforms due to the fun fact that a lot of custom configurations that affect PHP's runtime behavior are held in a system-wide ini file. External modules that allow certain features to work also need to be loaded from this configuration file. This makes having your application work consistently across platforms kind of a nightmare.
php.ini has its problems, but I don't understand this remark:
> External modules that allow certain features to work also need to be loaded from this configuration file.
What's wrong with this? The modules in question (at lest, most important extensions) are part of the core codebase and will be available as packages on whatever platform you're using, and the package manager should configure them for you.
The problem is that the distributed script(s), if the rely on external modules, will have to guess if those modules are available, rather than just bringing them with the script like other language dependency managers provide.
For example, with Ruby's gems or Node's npm, if I install a command line package, external modules (native C extensions) will be installed as well.
80 comments
[ 1.5 ms ] story [ 145 ms ] threadPerhaps Peachpie, when it reaches production quality, will also help with that, as then calling .NET (and maybe, through that, WinRT) APIs from PHP code will be made easier.
one example: https://docs.moodle.org/22/en/Administration_via_command_lin...
?
PHP enforces memory limits out of the box by default. What languages have execution limits on CLI?
http://gtk.php.net/index.php
There are plenty of companies that rely on PHP that also have to work with CLI. I believe they are better informed when it comes to making decisions between handling CLI via an entirely different language and sticking to PHP.
[COW ICON]
Let's stop and think. Do you know what the job is or are you calling it in with this comment?
To quote the Tarsana project git page...
The PHP language was chosen simply because I wanted to rewrite my lumen-generators using this framework.
Now I start to consider switching to Javascript...
because javascript.
Main reason for commenting is the current (and I'm sure more) comments questioning "why?" or "right tool for this job".
Please, HN overlords, please please add a flag (icon could be a cow) and total counts so that I may filter out such comments.
From the FAQ (https://news.ycombinator.com/newsfaq.html):
> Why don't I see down arrows?
> There are no down arrows on stories. They appear on comments after users reach a certain karma threshold, but never on direct replies.
I know Perl, C, C++ and PHP quite well, but I'd never, ever call C-like syntax a plus.
It's astonishing how feeble modern PHP is, that to comapre strings you often have to use strcmp. In 2017. It's like all the cruft of ANSI C with a whole bunch of $ characters spiked in.
It's the most common syntax pattern of popular languages. Statistically, more developers know a language with a "C-like" syntax than Lisp, Haskell, Erlang..
Well, versus whatever abomination bash uses, it's quite readable…
C-style syntax is fairly popular [1]. If it had lisp syntax or haskell syntax most people would complain that they can't figure out what's going on without learning all that syntax.
>that to comapre strings you often have to use strcmp
For equality === works just fine. For < and > there is no one obviously correct order, so it's entirely reasonable to use functions for that.
1: https://en.wikipedia.org/wiki/List_of_C-family_programming_l...
Vanilla PHP has better argument parsing than many recent hipster language. Go has some sort of ugly non conventional argument library which is barely usable, Node has none. But nothing beats vanilla Python for that tasks IMHO.
flag package bothers me because it breaks getopt conventions for no good reason.
This is not argument parsing. I'm pretty sure Node doesn't even do anything, it just gets an array of strings from the CLI, argv C style isn't getting options prefixed with - or -- directly from the CLI, and putting them in a map or something. So no, node has no facility in its standard library for that. Node is not known for its extensive standard library in anyway.
I built a small CLI app using PHP for HTTP load testing ( WIP ), check it out
https://github.com/vamsiikrishna/vex
But, the thing that struck me about this project and the examples is just how verbose PHP has gotten over the years. It is strikingly similar to old Java, in terms of class definitions and the like. I know PHP has also gotten faster and lot of "grown up" language features in that time, too, but some of its charm as a language with strong "whipuptitude" is lost. I'm certain it's a better language than it was a decade or two ago, and it was, frankly, awful by many measures back then. But, it sure does take a lot of typing.
So, I like that things like this exist (though I likely wouldn't use it...I really need most of my CLI tools to be standalone with no non-core dependencies). I'd like it if every web developer knew how to make good CLI apps and did so for every web app. I use Perl or POSIX shell mostly for my CLI apps, but PHP makes perfect sense for tools that work with existing web apps (the Drupal helper scripts I've written are mostly in PHP).
That's not to denigrate drush or the developer(s) of drush. drush is/was a remarkable improvement over the pre-drush era. I just think Drupal wasn't built to be driven by a CLI. It isn't API-native, by any stretch of the imagination, nor is it front-end agnostic. So, drush is historically working around rather than working with, and it shows in that most of Drupal is still inaccessible to drush (at least in Drupal 7; I haven't deployed Drupal 8 and probably never will as the migration from 6 to 7 was too painful for me to be willing to ever do it again).
So...I think we may just disagree on what "decent" and "finally" means. Also, compare to some other ways to build web apps; most modern web frameworks have pretty obvious ways to build CLI tools, and often are built around standard frameworks for doing so (Yeoman or generators/console in Rails). Drupal being based on Symfony now gets it a lot of that same kind of thing; so, it is recently decent, by my estimation. Others may disagree, of course.
I feel like Drupal could be a workshop on why "a wrong abstraction is worse than no abstraction". I'd assumed things were better on that front in D8, based on what I'd read, and based on the theory that at least the wrong abstractions would be common across everything (Drupal has always had the problem of a dozen different modules for every trivial thing, and every module needs a different combination of those trivial thing modules). I'd hope, at least, that database abstractions are nicer? The database API in Drupal 7 is, frankly, awful.
While Larry Garfield architected it, yours truly here put in quite some work implementing the API you like so much :) But that's just context -- I could ask you what are your problems but I won't, I am out and the API is frozen until D9. I would recommend filing an issue to tell what you don't like.
My problem is that by the time something reaches the database is it completely unrecognizable and is spewed all over the database in a half dozen tables. This is a problem of D7 much more than D6. It takes a handful of queries to build an "entity", for instance, and forget hitting the database from outside of Drupal.
Every CMS we've used in the past, I was able to use the database as the source of truth across many apps in many languages; the database was effectively the API I used to share data across our Perl and Python apps and Drupal. With Drupal 7 I can't do that at all. I have to go through Drupal to pull anything out or put anything into the database in a way that Drupal can work with it. It's just a pain in the ass. And, Drupal 7 is an awful experience for building APIs, so I can't really integrate stuff that way, either. I understand improving the API building experience is a focus for D8.
Anyway, I want my database to look like my model, and Drupal 7 doesn't do that. It spreads the model across a whole bunch of tables (I've got like 60 "drupal_field" tables in my D7 database...I have no idea what to do with all that mess). And, the APIs in Drupal to work with entities and fields and such are really ornery to work with and getting useful errors out of them is impossible. That's not the fault of the low-level database API, but it is the fault of how Drupal 7 implements putting things into the database. If that makes sense.
Mostly I've just realized Drupal doesn't fit my mental model of how CRUD apps should work, and working with it has been a real chore. I know lots of people are super productive with it, but in several years of poking at it in my spare time, I still don't "get it". I honestly still don't even have a good mental model for how the pieces fit together; it's so big, there are so many competing ways to do anything, it's full of re-implementations from one version to the next, etc. I can't make any sense out of it, and every time I come back to it it takes me hours just to get up to speed enough to make minor changes.
Like me. As far as I can see, while Symfony might be a decent framework but the integration between Drupal and Symfony is atrocious because it's an incredibly bad fit as the two systems had fundamentally different philosophies, mostly in the explicit vs implicit department. Compare a Drupal hook implementation to a Symfony event subscriber and you will see.
And I must be missing something what Symfony Console apps bring to the table compared to the absolutely trivial drush implementations... But each to their own, I guess.
It's all opt-in. Nothing forces you to use Composer, classes or even type hinting in PHP if you do not depend on third party libraries backed by composer. Most of C extensions from 10 years ago are still here and procedural code from that era would probably still work today on PHP 7.
But, maybe more importantly, this seems to be using classes where it makes little sense to use classes, but I see it a lot in PHP code. An idiomatic implementation of the same kinds of tools in JS/Perl/Python/Ruby might be shorter simply by virtue of not wrapping everything in a class. It's sort of an anti-pattern to OOP-all-the-things in those languages, while in PHP there seems to be a religious zeal for classes.
And yet nearly everybody does. Is there a compelling upside to justify that tradeoff? I can't think of a worse fate for a language than trying to mimic Java circa 1998, but that's exactly what's happening.
Something that probably hurts the language here is the lack of autoloading for functions, whereas it exists for classes, so exposing bare functions is a runtime performance penalty (their containing files must be loaded on every request, if you use Composer), which results in a preference for putting everything in a class. :/
AmPHP
ReactPHP
Kraken
And so on.
I want to run a PHP webserver and handle my own requests!
> External modules that allow certain features to work also need to be loaded from this configuration file.
What's wrong with this? The modules in question (at lest, most important extensions) are part of the core codebase and will be available as packages on whatever platform you're using, and the package manager should configure them for you.
For example, with Ruby's gems or Node's npm, if I install a command line package, external modules (native C extensions) will be installed as well.
Why would you choose PHP7 vs another language?
Why do you need this level of abstraction just for a simple command line function?