Would you agree this is the definition of a PHP framework?

Oh, I can’t leave this sitting either. If that is now your standpoint (which often seems to change, as it fits your argumentation), you need to go and correct your statement and definition of what a framework is and how you basically said Laravel is a library and not a framework.

Just to refresh your memory.

If you have to write your own code to call the framework components, then it is not a framework, it is a library. A “true” framework is in fact a mini-application with which you should be able to both generate and run your application components.


My definition of the differences between a library and a framework have not changed. It conforms EACTLY to the definition found in that Wikipedia article.

What is wrong with that description? Inversion of Control (IoC) requires that the processing flow be controlled by a framework component, not user code. This means that the framework should call the developer’s code, not the other way around. The framework code should also provide default behaviour. Take this one step further and it should be possible to use the framework to generate a working component which has this default behaviour. The only code that the developer should have to write is when he wants to override or extend the default behaviour.

These are the features which exist in Radicore but not in Laravel, as exhibited by the huge volume of code that the Laravel developer has to write in order to produce some basic CRUD screens. Compare this with Radicore where the developer can create basic CRUD screens without having write a single line of code - no PHP, no HTML, no SQL.

I can count higher than 3. How about these:

  1. Role Based Access Control (see http://www.tonymarston.net/php-mysql/menuguide/index.html)
  2. Audit Logging (see http://www.tonymarston.net/php-mysql/menuguide/appendixl.html)
  3. Activity based Workflow (see http://www.tonymarston.net/php-mysql/menuguide/appendixm.html)
  4. Data Dictionary (see http://www.tonymarston.net/php-mysql/menuguide/appendixn.html) which allows Model classes to be generated from the database structure.
  5. Transaction Patterns (see http://www.tonymarston.net/php-mysql/dialog-types.html) which allows user transactions to be generated from a pre-defined series of patterns.
  6. I18N (see http://www.tonymarston.net/php-mysql/internationalisation.html)
  7. Advanced security features (see http://www.tonymarston.net/php-mysql/radicore-security.html)
  8. Online help text (see http://www.tonymarston.net/php-mysql/menuguide/appendixf.html)
  9. Virtual Private Databases/Row Level Security (see http://www.tonymarston.net/php-mysql/virtual-private-database.html)
  10. Support for multiple sessions from the same device (see http://www.tonymarston.net/php-mysql/client-clones.html)
  11. Solution to the “back button” problem (see http://www.tonymarston.net/php-mysql/backbuttonblues.html)

These are features which solve user problems, not developer problems, so things like DI containers are completely irrelevant.

Ok. We found a common feature.

Can also be turned on in Symfony’s ACL component.

Not only one but a number of possibilities with Symfony.

I think Doctrine fills most of the concerns your Data Dictionary covers.

You lost me on this one. I looked through the docs, and only could come up with “WTF!”

Same with Symfony. For content translations, there is also Doctrine extensions.

Nothing special really. All in or extendable for Symfony.

Help text is content. Sonata can do content too. It would be too hard to program a help page system either.

With Symfony ACLs you can get field level security.

I am not sure what your multiple session system is for, but, with the proper permissions, you can log in as any user in a Symfony app in a separate window too.

Ok. This is another one where I go, “WTF!” I’ve never heard of the back-button being an issue for a server-side application and I read the linked page. It made me no wiser.

And, you missed the bigger points.

  1. SOA support. SOA being terribly important for an Enterprise application.
  2. REST (one way to connect).
  3. Templating for free style page creation.
  4. Composer support, so I can easily include libraries (and their changes from the 1000’s of devs supporting them) for the extra problems my own users asking me to solve.
  5. Unit testing, so that when I add the external code and my implementation of it, I don’t have to manually test all the parts of my application again manually, to make sure things aren’t breaking internally.

But how much code do you have to write to use this ACL feature? Radicore comes with its own database and maintenance screens, so you don’t have to write any code at all.

But does it have an pre-built AUDIT database and a set of screens instantly available in the framework to view the contents of the AUDIT database?

But you have to write your own code to use workflows. With Radicore you do not as it contains a separate WORKFLOW database and a set of maintenance screens. You do not need to write any code to use the workflow system.

Again you have to write code. With Radicore you use the screens within the Data Dictionary to import your database structure into the DICTIONARY database where you can amend the details before exporting each table’s details to produce its own class file. Does doctrine have its own database and a set of import/export screens?

So you don’t now what Transaction Patterns are? So you have never worked on an enterprise application which access hundreds of database tables using thousands of user transactions? If you had you would have noticed that several user transactions can follow the same pattern of structure and behaviour but where the only difference is the content.

But does it allow you to define separate tables for different translations of particular database tables, and does the framework automatically switch to those tables when you specify that you want the output in a different language?

But you have to write code in order to incorporate those optional extensions. With Radicore you do not.

This is about ROW level security, not FIELD level security.

It means that on the same device you can login as many times as you like to the application and each browser window will have its own session, not a shared session. This means that the user can browse through one part of the system in one window and another part in another window.

You have never heard of the “back button” problem? Have you tried google?

I do have support for web services, but that has to be customised for each user’s requirements.

I do not have templating for free style page creation as it has never been a user requirement.

I do not have composer support as it is not a user requirement.

I do not have unit testing as it would be far too expensive to retro-fit into an existing and huge application. Besides, it has never been a user requirement, and no user would be willing to fund an exercise that would take longer than the original product development and produce no visible benefits.

Not much.

Now you are talking about being more at an application level and not a framework level. Of course, there is no premade screens for accessing the stored logs. That is up to the client developer.

The language in Symfony is stored in different language files and transpiled to PHP a single time, so the code is ready at run time. No database calls. And yes, if you change the locale, the retrieved language is changed too.

As a software framework, the base behavior is supposed to be extensible through code (too). That is one of the main reasons to use a framework. You force your solution on your customer. Some might like that, others might not. It doesn’t make your framework any better.

I know what a transaction script is. I have no idea what you are explaining on the page you linked to. You do explain what a transaction pattern is here: http://www.tonymarston.net/php-mysql/infrastructure.html#controller.script

And if you read this gem about “anemic models”, if fits to what you are doing like a tee.

Field level security is a higher resolution for security. I am sure row level security can also be accomplished fairly easily.

So, in other words, because Symfony does have these things or at least can be very easily added, Symfony is way ahead of your framework. It might not be your customers asked for these things, but if they use Symfony, they can.


The fact that you have to write ANY code to use these features says it all. People like my framework specifically for the amount of code that they DON’T have to write.

It is built into the framework but instantly accessible to every application Model class without the developer having to write a single line of code. Logging for a particular class can be turned off by unchecking an option on a screen. The screens to view the logs are also available without the developer having to write a single line of code.

So what happened when you have descriptions in your PRODUCT database which need to be shown in the user’s language? I provide database tables and maintenance screens so that the user can define his own translations, and the framework will automatically retrieve from these tables when requested. All without having to write a single line of code.

I do not force my customers to use these options, yet all my customers - who are large corporations purchasing my enterprise application - expect those features to be there as standard.

The link I included in post #27 was this: http://www.tonymarston.net/php-mysql/dialog-types.html This contains a link to another article http://www.tonymarston.net/php-mysql/transaction-patterns.html which describes what the Transaction Patterns are.

Now you are contradicting what you wrote in Dependency Injection Breaks Encapsulation where you described my abstract class - which is inherited by ever Model class - as a “monster” class, a “god” class which tries to do everything. Which is it, then? Is it a class that does everything, or is it a class that does nothing at all?

In case you can’t read let me explain it to you - every Model class in my application takes care of all the validation and business rules that are required by its business entity. None of the other objects - the Controllers, the Views and the Data Access Objects - contains any references to any application components - no table names, no column names, no validation, no business rules. This is precisely as it should be - unless you want to argue the exact opposite.

But you don’t KNOW.

No. I consider my framework to be superior because it has volumes of features which can be accessed without the developer having to write a single line of code. This makes it easier, faster and less prone to error as the prewritten code has already been debugged.

Says what? It says the client coder of the framework has it in his hand to take care of, just like a software framework should offer. The fact you give the control to others says only that. You’ve made it easier for a non-coder to control access, which means you’ve written an application layer, like the client coder would. Sonata, for instance, is the same type of “back-end” application built on Symfony and allows the user to control ACLs too.

Again, this is application level work. This all isn’t part of the definition of a software framework anymore.

Like I said above, there is an extension for Doctrine, which allows the translation of the content, which would reside in the database.

I think you should call your framework a platform, because it is more than just a software framework.

I am not contradicting myself at all. You are typically twisting things for your own prerogatives. Read the Wikipedia article carefully. It says nothing about “doing nothing at all” and it sounds a lot like what you are doing with your transaction pattern. Martin Fowler calls that pattern “an anemic domain model”, simply because the logic is put incorrectly in a central place. That central place is your monster class? Oh yes…

A Transaction Script organizes all this logic primarily as a single procedure, making calls directly to the database or through a thin database wrapper.

The fact your monster class is a class and not just a procedure just shows how you have no grasp of OOP, if anything.

I can read and you can stop with your condescending tone. It is one thing to be ignorant. It is another to be ignorant and arrogant.

I actually don’t want to argue about anything, when it comes to you and your fabulous framework. But, you always push it to the forefront, like it is the holy grail of software frameworks, when it isn’t. It is a mountain of old legacy code, that has had its day. Those days are numbered. I’ll bet on it. Any company with any decent IT group, who has even the slightest knowledge of PHP coding standards and best practices wouldn’t come even close to using your framework. I’d bet money on that too. The fact you can still sell it only shows how ignorant some companies are.

I’ve never done it, so no. I don’t know.

And even then, when I think about it, row level access is actually not the right type of access control for an enterprise. Better would be a hierarchical access to data, which models the enterprise’s organizational structure. I know ACLs can’t do that, because it is a problem, which we still need to solve for our service.

You consider your framwork superior? We know this already. It is your problem. It isn’t superior. It is inferior.

For instance, how many devs work on your “framework”? (I’d still call it a platform for the reasons you just mentioned). One, two? With Symfony and all the bundles available, there are 100s. And, there are 1000’s of people testing these bundles and reporting bugs everyday. Your platform doesn’t have that luxury either. So I say, Symfony blows the doors off of your platform from a software framework standpoint by a long run. As a RAD platform, you might have the lead, but I’d still not touch your RAD platform, as it is not up to today’s standards. You can argue all you want about what today’s coding standard are and all you will be doing is wasting everyone’s time. Your platform simply doesn’t meet them. Period!

The framework should provide default behaviour which you should be able to use without writing any code. The only time you should need to write any code is when you want to override or extend this default behaviour.

I disagree. It is a component of the framework that is available to every application which is generated by and run with that framework. If it is a third-party component which you can only incorporate into your application by having to write code, then it is not part of the framework, it is a library.

If by a “platform” you mean a “super framework” or “more than a framework” then by definition you are saying that my framework is “super”. I will take that as a compliment :blush:

Yes you are. In one post you describe the abstract class which is inherited by every one of my Model classes as a “monster” class, a “god” class which tries to do everything, and in this discussion you describe it as a perfect example of an anemic data model. According to that Wikipedia article which you quoted this means the following

If you bothered to study my framework’s structure you will see that it implements both the 3-Tier Architecture as well as the MVC design pattern. This means that each Model contains code for data validation, business rules and task-specific behaviour, while all control logic is in the Controllers, and view logic is in the Views, and all data access logic is in the Data Access Objects.

This quite clearly shows that my Model classes DO NOT conform to that description of anemic domain models.

I repeat, all business logic is contain in, and only in, the Business layer, which contains all the Model classes.

A component script in my framework (see http://www.tonymarston.net/php-mysql/infrastructure.html#component.script for details) is not the same as the transaction script described by Martin Fowler

A transaction script has all the model, view and controller code in a single monolithic script, but my component script has just three lines, as shown in the following example

$table_id = "person";                      // identify the Model
$screen   = 'person.detail.screen.inc';    // identify the View
require 'std.enquire1.inc';                // activate the Controller

Does this match Martin Fowler’s description?

What ARE you taking about? My monster class, which is in fact an abstract class which is inherited by every one of my 300+ Model classes, contains all the methods necessary to enable effective communication between Controllers, Views, Models and Data Access Objects. It demonstrates the use of encapsulation, inheritance and polymorphism, so to say that it is NOT OO is unbelievably ridiculous and shows that YOUR grasp of OO is the one that needs to be questioned.

You seem to excel at both.

When you consider that the whole purpose of this discussion is “Would you agree that this is a definition of a PHP framework” instead of a library, then I must surely be allowed to describe how MY framework conforms to the four characteristics as described in https://en.wikipedia.org/wiki/Software_framework. Instead of discussing those four characteristics you, and your fellow members of the “paradigm police”, can do nothing except attack the method in which I have implemented them. Trying to have a sensible discussion with you is nigh on impossible. You are not concerned with the results that I achieve, only the “impure” way in which I achieve them.

I sell my software package to companies who either don’t have an IT department, or don’t have one which is capable of writing their own enterprise application. Coding standards don’t mean anything to them. There are only three things they are worried about

  1. Does the package do what they want?
  2. Is it value for money?
  3. Can it easily be extended and customised?

My software appears to be ticking all those boxes with a lot of big corporations, and I place more value on their opinions, and that of my business partner, than I do on those on a bunch of know-it-all developers who have never written an enterprise application in their lives, let alone a customisable package which can be sold to may different organisations.

Then you would be wrong. My latest customer has specifically asked for row level access in a certain part of his application, and this I have been able to provide for him, thus beating a rival application which could not.

You believe what you want, and I will believe what I want. I put my faith in the customers who are willing to pay big bucks for my enterprise application and my framework and not some know-it-all developer who has never written his own framework or enterprise application.

Symfony is a collection of libraries and third-party plugins, it is not a framework.

I don’t care about today’s coding standards as they are just a passing fad. I prefer to stick with those standards which have stood the test of time.

So you are redefining what a software framework is now?

Nope, it is part of the application using the framework.

Oh my. NO! More than a framework yes. You have done application level work. A super framework, as in super good! HAH! No way.

Which you’ve constantly said are all dependent on your abstract monster class for their methods.

Are you kidding? From that little piece of code, I’m supposed to surmise that? That is like me looking at the hood of your Mustang and asking me to tell you what type of spark plugs are being used.

Hah! You said it again.

You thinking you are encapsulating and following SRP with a 9000 line, 100+ method class is the ridiculousness here. Nothing else.

Yes, let’s get back to the point. Funny, I say you do “application level work” and then you say, no you don’t and yet, your definition is the following.

If you have to write your own code to call the framework components, then it is not a framework, it is a library. A “true” framework is in fact a mini-application with which you should be able to both generate and run your application components.

So which is it? Are you doing application level work with your framework, or aren’t you?

Well good for you. It doesn’t prove me wrong, nonetheless.

You see, that is where we differ completely. I know I don’t know it all, where you think you do and seriously don’t.

But, it does fulfill the four points of a software framework, which you said is all a framework needs to do to be one.

Oh brother. A passing fad? Right Tony. First, you are admitting that there is a standard. Something you hadn’t done earlier. So I’ll take that as a win.

And you might be right. What we are doing today might be different in the future and probably will be. However, the standards we use now are what most good programmers are using and you can be rest assured, we are never going back to PHP4 or early PHP5 days of coding. Those days are long gone, just like your hole punching Cobol days. Why aren’t you still programming like that? It was great at the time, wasn’t it? You missed the PHP advancement bus 10 years ago and you aren’t even trying to get back on it. That is your only real and major mistake.


@tony_marston404 Why is it so important to you to argue over whether something is a framework or a library (or whatever)? Even if the PHP community suddenly decided, en masse, to adopt your usage of the word framework and rebrand Symfony, Zend, Laravel and the like as libraries, what difference would it make?

I would argue that this thread is not constructive and should be closed by the mods.

1 Like

I think what he meant there is his framework has a solution to the form re-submit issue (back button on browser & hit refresh) where a user can use browser history to go back & re-submit a form by hitting refresh. Umm, people learned to solve that particular thing like 10-12 yrs ago & thats touted as a feature of his framework?!! Oh my! :expressionless: I guess he doesn’t know about simple things like redirects on form submit (thus no way to spoof re-submit that damned form via history) & nonces. 10 yrs from now he’ll learn about CSRF attacks, nonces & that will be the new advanced security feature in Radicore. :wink:

Also, he mentions 3 ways of maintaining state for a user - hidden fields, cookies & server side sessions & promotes server side sessions as best. Right, because every web app needs only one server to run, nothing more than that.

I think my IQ just dropped 20 points to 120 after reading all that, though its good to see level of my patience has increased significantly having gone through all that (new personal best)! :wink:

Radicore is an “enterprise” framework and since it most likely will sit (actually will have to sit) behind a firewall and only have external access through a VPN, such security features aren’t necessary. Things like using nonces or CSRF protection are solutions to problems Tony’s framework doesn’t have. Did I do a good job there Tony?

It would mean I and probably a good number of other people would lose a lot of respect for the PHP community.

That is a actually good lead into getting back on topic and to the whole point. The issue here is, Tony has built what he calls a framework, but has also done client coding to “ease” their workload, which is fine and dandy.However, he considers that client code part of a good framework and anything less is just a library.Whereas, the frameworks of today do not have much client code at all. And they shouldn’t. The frameworks should be a foundation for any number of applications, even the basis for what I’d call an extended framework or platform, like Tony’s.

The only real problem we have here is Tony’s own feeling of inadequacy with his framework. Oh, he won’t admit that he has this feeling and he probably doesn’t realize he has it himself. It is most definitely subconscious. But, the feeling of inferiority clearly drives his motivation to pick out articles on websites like Sitepoint to point out how inadequate a framework is, so he can prove (more to himself than anyone else) that his framework is more than adequate. If he were actually sure of himself, he wouldn’t need the “mental reduction” of other frameworks to “libraries” or the constant fighting he does against modern PHP methodologies or the long winded reasoning on his website for why he does things, as he does them. Deep down inside, he knows what he has is a lot of CRAPpy code. Deep down inside, he knows the PHP world is flying past him.

Again, he won’t admit to it. Instead, he not only doesn’t stay quiet and simply be proud of his work, no, at any chance he finds, he tries to lower the value of other people’s work. Or insults them by saying they are incompetent or monkeys or whatever else he finds to belittle everyone else, which raises himself internally to a higher, better place. It is called a superiority complex.

Nonetheless, I am using Tony’s superiority complex as motivation to learn myself. It is like a sparring partner in boxing (and just like in boxing, sometimes punches go too low). I am sorry if that gets on people’s nerves and apologize for the low blows (which mods have deleted), but I find it fun and I am learning a ton while sparring with Tony and no, not to learn what Tony teaches, although not all of what he says is completely wrong. In fact, some of it is completely right. However, the basis from which he works off of, his “framework” and his antiquated coding style, is totally not right at all from a modern coding perspective. It is this basis, that holds Tony back IMHO. Again, he won’t admit it. And to be honest, I hope he won’t. I’d lose a sparring partner. :smile:



Just as a note to show what a young company is looking for in a PHP software framework, I just ran into this very good post.


Very enlightening insights. I love this sentence:

Believe it or not, all of the following factors matter first for the business, then for the developers.


Well said

No, I am simply echoing the description found in https://en.wikipedia.org/wiki/Software_framework

Nope, if you have to write code to call “it” then “it” is a library. If “it” calls code that you write then “it” is a framework. If your code controls the processing flow, then you are using a library. It “it” controls the processing flow, then “it” is a framework.

Yes. That is what abstract classes are supposed to be for, to define in one place all the methods which may be used in any of the concrete classes which inherit from that abstract class. The fact that my abstract class is bigger than anything which you have ever written simply means that I have created more sharable methods than you can possibly think of.

Martin Fowler’s description of a transaction script (see http://martinfowler.com/eaaCatalog/transactionScript.html) does not match my component scripts (see http://www.tonymarston.net/php-mysql/infrastructure.html#component.script). You need to actually READ both articles to understand why.

Your definition of SRP is totally skewed. It says that I should take a monolithic piece of code and break it into manageable modules with separate responsibilities, such as presentation logic, business logic and data access logic. This is EACTLY what I have done by implementing the 3-Tier Architecture. By going too far and breaking these modules into smaller pieces you will do nothing but end up with a fragmented system in which all unity is lost. My Model classes do not contain any control logic as that is held in, and only in, my Controllers. My Model classes do not contain any view logic as that is held in, and only in, my Views. My Model classes do not contain any data access logic as that is held in, and only in, my Data Access Objects. There are no methods in my Model class which do not belong in my Model class. There are no methods which I can move into other classes, and if I did move them I would end up with more code as I would have to instantiate another class before I could call any of its methods. Every competent programmer knows that having too many classes makes your code slower.

My framework is a mini-application insofar as you can “run” the framework, and there are online screens in the framework which allow you to generate new components for your application, and then run those components which have default behaviour until to insert code to do something different or extra. The framework therefore provides default behaviour which is of use to the application, but the processing flow is still controlled by the framework, which makes it a “true” framework and not a library.

Yes it does. You said nobody would need that feature. The only reason that I added that feature to my framework because customers (note the plural) specifically asked for it.

So you admit that you don’t care what the customers think of the software that you write provided that your fellow developers think that it is “cool” and “pure” and written to “proper” standards.

No it doesn’t, by virtue of the fact that you have to write reams of code yourself before you can do anything. After you have installed this thing-which-masquerades-as-a-framework, can you run it? Can you generate application components with it? Can you then run those components with it?

Wrong again. I never said that I don’t follow proper coding standards or best practices. I most certainly do, but they do not happen to be the same as the ones which you follow.

This is called “default behaviour” which is what a proper framework is supposed to supply.

Wrong again. If you have to write code to call “it” then “it” is a library. If “it” can call code that you write to change the default behaviour that “it” provides then “it” is a framework.

If they do not supply any code which the application can use as “default behaviour” then they are missing one of the prerequisites of a framework.

I would never have guessed that from your constant stream of vitriolic attacks. If you actually agree with some of the things that I have written, can you point them out so that I can change them? It is simply not the done thing to agree with ANYTHING that I say. :grinning:

It is important because once something has been defined, then nobody should be able to come along and change the definition to mean something else entirely. The fact that some programmers have created libraries which they call frameworks does not automatically make them frameworks. Some people could also attempt to claim that left is now right, up is now down and in is now out, but that would be very confusing and very wrong.

Suppose some clever-clogs comes along and tries to change the definitions of encapsulation, inheritance and polymorphism? How much confusion would that cause?

Where in that whole article is it stated a software framework will allow you to, “use default behavior without any code”?

Sounds like what Martin Fowler calls the Super Class smell/ anti-pattern.

I thought we were talking about your transaction pattern?

SRP says, a class should only have one responsibility and need to be changed for only one reason. Your 9000 line monster class has several reasons for changing. Some make sense, and some actually don’t.

So we agree. You are doing more than just a framework with your framework.

I took your comment as calling me a know-it-all and I said, I know I don’t know it all and never will. You, on the other hand, think you know it all or act like you do.

Where is all that in the definition of a software framework? Please point out in any definition of a software framework, where the client coder doesn’t have to code, where, when a framework is installed, it must run somehow (which today’s frameworks do, to a point), that a framework must generate components (which some of today’s frameworks also do) and run with them. Where is that defined?

Boy, you totally flew by the point. You said, “I don’t care about today’s coding standards…”, while the whole time you have been saying there are no coding standards or best practices. Now there are? How much of PHPtheRightWay do you agree with? Probably not much. That is a standard and it is full of best practices.

No, it is application code.

That is another new definition. Where can I find it in the definition of a software framework?

But they do supply a ton of “default behavior”. Authorization, authentication, session management, configuration management, DI container, routing system, etc., etc. The application / the client coder can use all of it, or none of it.

There isn’t too much I agree with, but I do agree with your conviction to not simply take everything at face value and to question the status quo. I also agree that it isn’t worth the effort to take a huge mound of legacy code and try to make something modern out of it. I’ve seen such an attempt fail miserably, partially because of the code, but mainly because the devs that attempted it just weren’t up to the challenge. And even if they would have been up to the challenge, the effort should have been put in rewriting the application from scratch. There are some people who say refactoring is always the best way to go, however, when the code is so old and the application not that complicated, then I feel a rewrite is better.