I designed a PHP 5.5+ framework comprised of more than 750 different classes to make both web applications and websites.
I would like to, ideally, be able to reduce its size by producing a version of itself containing just the bare essential files and resources needed for a given project (whether it's a website or a web application).
What I want to do is to be able to:
reduce the amount of traits, classes, constants and functions to the bare essential per project
compress the code files to achieve a lesser deployment size and faster execution (if possible)
So far, I've got the second part completed. But the most important part is the first, and that's where I'm having problems. I have a function making use of get_declared_classes() and get_declared_traits(), get_defined_constants() and get_defined_functions() to get the full list of user-defined classes, traits, functions and constants. But it gives me pretty much EVERYTHING and that's not what I want.
Is there a way to get all defined classes, functions and constants (no need for traits as I could run class_uses() on every class and get the list of traits in use by that class) for a single given script?
I know there's the token_get_all() function but I tried it with no luck (or maybe it's I'm using it the wrong way).
Any hint? Any help would be greatly appreciated :)
You can use PHP Parser for this. It constructs abstract syntax trees based on the files you supply to it. Then you can analyze its output for each file, and produce a report usable to you.
Other than that, you can use token_get_all() approach you've mentioned already, and write a small parser yourself. Depending on your project, this might be easier or more difficult. For example, do you use a lot of new X() constructs, or do you tend to pass dependencies via constructors?
Unfortunately, these are about the only viable choices you have, since PHP is dynamically typed language.
If you use dependency injection, however, you might want to take a look at your DI framework's internal cache files, which often contain such dependency maps. If you don't use such framework, I recommend to start doing this, especially since your project is big and that's where dependency injection excels at. PHP-DI, one of such frameworks, proved to be successful in some of my middle-size projects (25k SLOC).
Who knows? Maybe refactoring your project to use DI will let you accomplish the task you want without even getting to know all the dependencies. One thing I'm sure of is that it will help you maintain it.
I am using my own home grown PHP framework and it is heavily based on components mostly from pear and Zend but lately there are some better components coming up at Composer
As my apps are growing it becomes harder to switch between components, and I am wondering if there is a way I can design my programs differently. In a way that would allow me to use components like the opposite of abstract classes.
I am thinking there should be a way for me to create my own classes, which in turn just hook in to pear or zend and use those classes like as if they wore interfaces or abstract classes. Of course they would be doing the actual work and I would just link to them.
Hypothetically if I have been using pear Config/Lite, which can only work with ini and array files, and now I like to switch to pear config or Zend config to get the benefit of saving the data in a database then there should be an easy way to switch without changing all my code since what they implement is exactly the same thing.
I am asking because I been using pears Net/URL/Mapper, which isn't bad but I found something that would also take care of the dispatching, and is being actively developed. Also I am sure that this kind of situation will come up again and again.
You want to look for something like the facade design pattern, or just use delegation / composition. However beware, using something like a facade can lead to a lot of unneeded complexity as you add layers of abstraction. I recommend you read some php design patterns, especially delegation / composition of objects to get a feel for how that might fit your case.
You should use composition for this IMO. Have the classes in your library expose their own public interface, which the rest of your code depends on. If you ever change the underpinnings of a component from say PEAR to Zend, just ensure all the original public methods still honor the previous version and you should be golden. You can formalize these interfaces with the interface keyword if you wish, but that is beyond the scope of this answer ;)
For the life of me, I can't seem to wrap my head around "classes" in PHP.
I have managed to write large, scalable, and popular websites without them.
What am I missing? (And how do I learn?)
Classes will help with code re-use and potentially a very structured application.
Procedural programming can be a lot faster in both development time and execution speed.
OO programming is the more mainstream way but not always the best way. Theres a book called PHP Objects, Patterns and Practice which is a very good read, it covers the basics of classes, why and how to use, abstraction and common design patterns such as MVC. It also covers unit testing and other very good practices for php developers
The point of classes (object oriented programming) is that it bundles data together with the code that operates on it. If done well, this leads to less tightly coupled and thus more maintainable code.
In practice it means fewer global variables (whether used directly or accessed through static factory methods) and lesss passing around of data (i.e. smaller method signatures).
For a concrete example, look at the Mysqli extension: each function has a procedural and an OOP version, and the procedural version nearly always needs to have an extra "link" parameter to give it context, wheras the OOP version gets that context from the current object.
Everybody answered was right you are missing a lot because let's say you have a photo gallery website
instead of writing functions and in the end you end with a lot of them
OOP would be useful in:
Code organization and maintainability
Adds clarity, and reduce complexity
Emphasizes data over procedures
Code modularity
Code re-usability (Believe me you will need that a lot)
Well-suited for databases
I wasn't using OOP before but i started and to be honest not very long time ago, and found it very useful in those points specially in the re-usability of the code
Let's say i have a photo gallery website
i will create a class for users and this class will do CRUD on all of the users table
and a class for the photos to do the CRUD on all of the photographs table
I could also make a class to do all the CRUD for me without specifying on what table
and then use the inheritance to extend all the CRUD in my users class and my photograph class
the point in that is i could only write the CRUD methods once
and then re-use it in all of my other classes
I hope i would have answered your question
IMO, If you do not wish to seperate your htmls & php code; you better not use classes.
You'll need them in a framework environment (not necessarily), and you'll need them if you want to objectify your datas, handle them like that.
but if you're fine without it, then you're just fine :)
When it comes to handle a very complex system, with a lot of different data structures, more than one team members, etc. You and your code need to be organized very well, and you'll need classes.
Good question! You got my upvote!
Straight to the point:
You're missing a whole world!
There are many metaphors to describe it but there's nothing better than practice - you obviously know it after "years" of programming!
Decide on a small project and write it OOP style. Then you'll get the idea.
Take this tip as well: Name your classes as their file names (ex. "MyClass" -> "MyClass.php"). Easy to maintain.
You are probably missing testability: I guess your functions call other functions, which in turn might call another function, right? So you will have trouble testing an isolated function. With OOP you assemble "heaps" of objects and can interchange each object with a "fake" one (called mock or stub) for a test. This way, you can test each functionality in isolation. Think of being able to test you output code without needing a database. Think of testing your controller code (the code which processes the request parameters and decides what action to take) without needing a web server.
I'm fairly new to OOP in PHP, I've made a couple of basic scripts but nothing impressive. All I've really taken from it is that it would probably be easier just make a collection of functions and include them.
The structure of classes seems to just confuse what was otherwise a simple process. And in collating everything into a class it doesn't really add any functionality.
So I'm clearly missing something. Could someone explain what functionality is added by creating classes
Classes are a notion of object-oriented design (and programming and analysis, respectively), where they are used to encapsulate data and methods.
Other object-oriented programming techniques may include features such as
information hiding,
data abstraction,
encapsulation,
modularity,
polymorphism and
inheritance
From an article .. top-15-best-practices-for-writing-super-readable-code:
Object oriented programming can help you create well structured code. But that does not mean you need to abandon procedural programming completely. Actually creating a mix of both styles can be good.
From http://java.sun.com/docs/books/tutorial/java/concepts/class.html:
In the real world, you'll often find many individual objects all of the same kind. There may be thousands of other bicycles in existence, all of the same make and model. Each bicycle was built from the same set of blueprints and therefore contains the same components. In object-oriented terms, we say that your bicycle is an instance of the class of objects known as bicycles. A class is the blueprint from which individual objects are created.
Finally, a short youtube video about the differences between the procedural and object-oriented programming paradigm ...
While it may at first look simpler to just use a set of functions and include them, classes have their strong points. Classes can store variables and those variables are there "later."
Here's an edited example from php.net
<?php
$item_name = 'Widget 22';
$item_price = 4.90;
$item_qty = 2;
$item_total = ($item_price * $item_qty);
echo "You ordered $item_qty $item_name # \$$item_price for a total of: \$$item_total.";
?>
v.s:
<?php
class Item {
protected $name, $price, $qty, $total;
function __construct($name, $price) {
$this->name = $name;
$this->price = $price;
}
function calculate($qty) {
$this->total = number_format(($this->price * $qty), 2);
}
public function __toString() {
return "You ordered ($this->qty) '$this->name'" . ($this->qty == 1 ? "" : "s") .
" at \$$this->price, for a total of: \$$this->total.";
}
}
$widget22 = new Item("Widget 22", 4.90);
$widget22->calculate(2);
echo $widget22;
?>
Another huge benefit is that you can make more of them. Say you want to calculate the price of another item and print it. Instead of having to duplicate all the fancy logic, you can just call new Item and be done.
A big advantage to OOP is code reuse. An example: Say you design a generic "Socket" class, which communicates with a server at a very low level. Then, I may come along and decide that I want to write an FTP class, which allows a user to download files while connected to an FTP server. I can "subclass" your Socket class and extend its functionality to support FTP, without rewriting your code.
Now, say John wants to write an HTTP class, to interact with HTTP servers. He, too, can subclass your Socket class to accomplish this, without rewriting the low level socket code.
Notice how in this example there was no duplication of socket code; both me and John shared it. Code duplication is bad because if there is an error in the duplicated code, the exact same bug may occur somewhere else in your code and you may not realize it.
More detailed information about classes can be found on Wikipedia.
Classes are a way to organize programs. Classes can be used to represent entities in the real world, or artifacts in our programming world, reducing the complexity of programs by allowing us to reason about them in terms of a higher granularity.
It is well-known in psychology that experts organize knowledge into "chunks" to allow them to reason more easily and quickly about their domain. Classes allow us to reason more easily and quickly about our programs.
In addition, classes allow us to group together the knowledge about an entity together with the methods/procedures/functions/operations that are naturally associated with that entity. Again, this provides a natural way to organize the information in our programs.
There are other advantages of classes, such as inheritance, but primarily classes are a cognitive way of organizing program structure to reduce the complexity.
Just a coupl months back I was posting similar questions about classes, I have been using PHP for a few years now and I really didn't see a need to use classes, they just complicated a simple process like you said, well I finally decided to jump in on the Class train and I am still learning but I am comfortable using them now and WOW I have a completely opposite way of thinking about them now, I think they are the best feature in PHP now!
I will admit they can be overkill for a small application but a large social network site like mine is far from small, it has hundreds of files and now that I am converting over to classes it is structured much better now and easiar to build, update, manage my code and other users could come in and understand my whole site a lot better now that it uses classes. Another great feature is you can break up all those functions you might have into seperate class files and use autoload() function to auto load the correct file only when the class is needed, this is great on a big project too. Classes make things more plug in play.
All I can say is it's kind of one of those things you need to dive into to see the REAL benefits of it.
I have thought exactly the same thing.
I have read a few books on OO-PHP, my favorite being PHP In Action.
Although when I read the books I thought "Hey, this is very useful and interesting information.", I have yet to use a significant amount of OO-PHP.
Simple needs like getting info from the server and JSON-ing it back really dont need OOP. Im sure it is "Best Practice", but for many people's needs it isn't practical. A few classes, like database connection, and similar data handling can be real time savers, but PHP is sometimes easier and quicker to be used only partially OO.
It would definitely be easy to code in procedural programming (that's what your simple process is called) if your website is small. But as your website grow, you will definitely need to sort things.
For example, you will need classes to act as templates for entities to the database. You might need classes to represent each page, and in a single file you might create multiple pages. Thus these are all advantages of OOP.
In another example you have like 40 over functions. You would want to group them together. Putting them in a class as static methods would definitely help. It'll clean things up so that in future when you come back to the same code, everything looks familiar to you.
I always thought the same thing until I started using classes--realizing that it is so much simpler and better.
You should create those functions that you're mentioning, but gather them all within a class. The functions can then within a class share the same variables, and therefore making it simpler when having to use the same functions multiple times.
The best example I can come up with now is connecting to a database.
Instead of having individual functions that connect, sends a query, fetching the results and closing the connection you could wrap all these functions within a class. This would allow you to communicate to the database multiple times using the same functions, without having to make loads of variables tailored for the specific use on the page.
If you're just writing procedural-style functions then slapping them together into a class you're not going to get many of the benefits of OOP. I think that the Open Closed Principle and the Dependency Inversion Principle describe some of the biggest benefits of OOP, which you wont get unless you intentionally design them into your code.
OOP isn't perfectly suited to everything, though. I think procedural programming is well suited to web development. It involves converting a (fairly) simple request into a bunch of HTML, which is a highly procedural task. If it's simpler to include a few functions, there's no point trying to shove an OOP shaped block into a procedurally shaped hole. However, I imagine that OOP would be the better option if the website was very complex.
All of the above poster have really good points. I would highly recommend the following books:
The OO Thought Process: http://www.amazon.com/Object-Oriented-Thought-Process-3rd/dp/0672330164/ref=sr_1_5?ie=UTF8&s=books&qid=1262547120&sr=8-5
PHP5 Objects, Patterns & Practice: http://www.amazon.com/PHP-Objects-Patterns-Practice-Second/dp/1590599098/ref=sr_1_3?ie=UTF8&s=books&qid=1262546817&sr=8-3
OO Design Heuristics: http://www.amazon.com/Object-Oriented-Design-Heuristics-Arthur-Riel/dp/020163385X/ref=sr_1_1?ie=UTF8&s=books&qid=1262546869&sr=8-1
To manage complexity.
Edit: Maybe I shopuld elaborate a bit more.
Programs are complex entities and many ways have been proposed historically to tame their complexity.
Procedural programming, functions, structured programming, abstract data types and object-oriented programming are just models to help programmers manage the mental effort that is required to understand a program.
Object programming will not solve everything, and certainly for a small script it is overkill, but it works great for big applications or systems.
My original answer tries to summarize the full content of the humongous Code Complete book: do your best to manage complexity and make your programs understandable for you and your successors. It's great if you think that object programming will help you in this task, but it's even better that you question its convenience and try to find better ways.
In PHP, classes can, at the very least, save you a bunch of include statements. The lazy loading of the __autoload() function is very handy. Also, you can be confident that function names in different includes won't conflict.
To go beyond that, you can start to think of creating an API around a class. Functions which are needed only by other functions within the class can be marked private. And eventually, you should be able to ignore the actual code in your classes, and just think of them as API calls.
If I call Do::stuff($a, $b) I get this response.
And that's all you need to know. You can forget how it works "under the hood" inside the class.
And then, of course, there's classes with non-static functions. These can do various interesting things that normal functions can't.
I have returned to php development from Moose and I really miss CLOS like object model for php. Is there some kind of syntaxtic sugar which would allow me to write less code in php when dealing with objects?
Just to stress this requirement a bit more. I don't want to write one thing in several places. I can live with part of code being generated automatically, but in the code that I have to see to develop I don't want to see redundant information which is just clutter (think: LISP macro if you really need more analogy). So this part can be also called DSL if that makes more sense.
I would love to have at least roles (mixins), and some kind of introspection without re-inventing the weel. Code generators and auto-loaders might be one way to solve at least part of this problem.
p.s. For JavaScript there is Joose, so similar API would be very useful.
There are no mixins in php yet but there is an RFC for traits which will work roughly the same. http://wiki.php.net/rfc/traits
Using overloading for __call can allow you to dispatch methods to other classes and have it look like a mixin.
The Symfony project has a mechanism for mixins, allowing aspect oriented programming like in CLOS. Personally, I don't like this kind of hacking in userland spacee (At least not with PHP). I think you would be better off using the features that the language provides, and perhaps wait for something like traits to (maybe) make its way into the language.
There is also new project http://github.com/huberry/phuby which implements roles in php!