Im a newbie PHP programmer and I have a few questions about creating a REST based API service.
Basically, its going to be a github open source project which is going to scrape various data off the web and offer it as an API in XML. Now here are my questions in terms of how should I or how can I do this.
1) Since there isnt a robust/same pattern for getting various data through scraping, what is the best way to actually output the xml?
I mean the PHP file would have various lines of extracting data from various points in the code and the file would be a lot of lines. Is it a good idea to type the code to output the result in there?
2) Is there a way to organize the scraping code in a sort of class?
I cant think of a way that would work besides linear approach where not even a function is created and you just apply functions (in general).
3) If theres a way to do that ^^ , how can it you output it?
Is there any other approach besides using another file and getting the contents from the main file and displaying the code through the secondary file.
4) If I were to offer the API in XML and JSON, is there a way to port from one result to another or will I have to manually create the fields in json or xml and place the content in there?
I might have more questions that might arise after these have been answered but I hope I get everything cleared up. Also, this is assuming that the results are not fetched from a DB so the data has to be scraped/tabulated on every request. (even though caching will be implemented later)
Thanks
This question is probably more appropriate on https://codereview.stackexchange.com/
Not to be rude, but a newbie programmer developing an API is like a first-year med student offering to do open-heart transplants for free. I understand that you believe that you can program, but if you intend to release publicly accessible code, you probably need more experience. Otherwise guys like me will muck through it and file bug reports ridiculing your code.
That said, if you want theory of good API design you should probably check out Head First Object Oriented Analysis and Design. You'll want to focus on these key concepts
Program to an Interface, not an Implementation
Encapsulate what varies
...and follow other good design principles.
...honestly, there's a lot to cover to good interface and good systems design. You can use this as a learning exercise, but let people know they shouldn't rely on your code. Though they should know that screen scraping is far more brittle and instable than web service API requests anyway, but many don't.
That said, to provide some initial guidance:
Yes, use OOP. Encapsulate the part that actually does the scraping (presumably using cURL) in a class. This will allow you to switch scraping engines transparently to the end user. Encapsulate your outputs in classes, which will allow for easy extension (i.e. if JSON output is in a Single Responsibility class and XML Output is in another, I can add RSS Output easily by making a new class without breaking your old code)
Think about the contracts your code must live up to. That will drive the interface. If you are scraping a particular type of data (say, sports scores for a given day), those should drive the types of operations available (i.e. function getSportsScoresForDate(date toGet))
Start with your most abstract/general operations at a top level interface, then use other interfaces that extend that interface. This allows users to have interfaces at different levels of granularity (i.e. class SensorDataInterface has a method getData(). HeartRateMonitorInterface extends SensorDataInterface and adds getDataForTimeInterval())
Related
I started learning oop about 6 months ago, although I stopped for a while because of studies.
The problem is that whenever I use oop in my project I usually try to just make every single thing a class... Whether intialization, displaying, looping and much more... to be precise, I haven't gotten the concept of when to use/create classes.
Another problem is that I tend not to know the major benefit of a classes over a functions . Currently, I just mix them up.
I watch a youtube video that talks about classes and client code. In that video they said that classes are more of like developer codes while client codes are codes we write which uses the developer code to make things easier. So he advise we break our code to client/developer code.
But I don't know how to break my code into client code and developer code.
Infact at a point I was creating classes for all my pages like index.php, about.php
<?php
class about{
public $title = 'about page';
public $page_color = 'red';
//functions and more codes
}
After writing the above code I know I am not doing something right. I have tried to search google and have read many oop books but each time they use the car class example which I can not apply to my coding or just wouldn't address the context were a class is or isn't necessary.
Note: I am comfortable building website using procedural codes but I need to learn oop incase I need it someday.
To answer your question: Yes you're using it incorrectly. However it's not a quick fix to get you using it correctly.
There isn't an answer I can give you that will mean you start writing perfect OOP code tomorrow.
You're on the right path, study and practice. Make mistakes, live with those mistakes and refactor them. You'll get sharper the more you do this.
I'm at 16 years experience and I still find new rules and exceptions in OOP. It's not an exact science - it's a method that can yield different results depending on the context.
Just look at all the comments you've had and you'll see no general perfect consensus. Everyone is iteratively improving each others implementation. You can use this approach in your code, keep it tidy and organised, swap bits out as you find better or more correct ways of implementing them.
Well I have not learned php. But I am a good Java developer. And my OOP concepts are good. You mentioned that you do not understand major advantages of classes over function. Both of them are totally different. A class is a blueprint of software.Where as a function represents behaviour of software. You write all the code that does the processing of data provided as input by user and generation of output in functions. Classes contain these functions. The major advantage of writing code in classes is that they can be written in one place and reused anywhere. And OOP concepts are too vast. Each and everything cannot be explained in posts. OOP is much more advantageous than procedural-programming. Consider you are working on a very big project. Some features in the software are common. In OOP you can write code in one place and use them wherever you want.Whereas in procedural-programming you have to rewrite the same code wherever you are using those features. So, your headache of writing code will be minimized in OOP. Also, if the common code works on one place it will obviously work wherever it is being used. This is how OOP evolved from procedural-programming.
OOP is the backbone of most programming languages so you will want to use it basically all the time when you have it fully understood.
Websites are a little trickier to give you good examples of so I'll try and give a generic outline and then a more web-based focus.
Classes should hold data that is related to each-over in a common sense name. For example a Car would obviously hold the Engine (another class), the colour, the name, the owner, etc. And within that the engine would hold it's own set of data that is relative to it (max speed, miles per gallon, etc.). This is the basis of holding your data together, next comes functions within classes.
Now while Car holds data relative to the car, Car also holds functions that the car would do, or functions that the car will use to interact with it's data. Getters(GetColour()) allow outside objects to get information about that specific car (as Car1 and Car2 could hold different colours). Setters are the opposite, to set object specific data. Then we have everything else. Car.start() which internally calls this.engine.start() which may set up some functions to start draining gas from the engine and allow the car to move.
Classes are all about having this easy to read, easy to understand, and easy to re-use. Once your Car class is complete you can re-use as many cars as you need and they are all nicely self-contained.
On to web
Firstly, I highly recommend you look into MVC architecture, which is where the bulk of web architecture is and makes OOP easier to understand for web. Basically your website is split into controllers (in charge of interracting with the DB and giving you back the page), models(Your database data, e.g a user) and your views (HTML with a little templating so your controllers can pass it dynamic data)
For example: You go to website/posts/Stanley , Your Router (another MVC thing) decides that this needs to be handled by the PostsController(a class). The posts controller knows that you want all posts by user Stanley, so it asks the Posts Model(a class)to retrieve all posts by Stanley, the controller then passes these to the view to fill out a template using your Stanley specific posts.
Going away from MVC a second,
With your example given, you will mostly use classes, I would assume, for data manipulation and DB access. For example if you stored blog posts in a database you may have a class Blog with data that matches your db rows (id, user_id, title, body) and functions to access that data to put in your HTML, but also to grab that from the database easily.
For example:
BlogPost::All() may return an array of every blog post newest to oldest.
BlogPost:By(user_id) may return an array of posts by a specific user.
BlogPost:Remove(id) may remove the blog post given it's id.
BlogPost:RatingAtLeast(starRating), get all blog posts with atleast a starRating rating.
You get the idea... This class would exist as you said above, to give you a client code way to access your database that is SPECIFIC to your use case and as BlogPost contains variables related to your BlogPost. So BlogPost::All() will return an array of BlogPost.
I have developed a Web Interface for managing our devices (Dedicated Servers/Switches/etc) at work, however with my basic PHP knowledge, I ignored OOP completely. In the current state it just queries the MYSQL Database and populates the tables. Functions are all stored in a Functions.php file and called as needed.
As the project is functional and used now, I would like to rewrite this to be more efficient as it will be used among our other brands. I am having trouble applying the concept of classes to this project though (I use them all the time in C#/C++).
The way I see it, each Device be it a server, switch, etc. could be a part of a Device class that keeps properties like Datacenter, Name, etc. and methods such as Update, Delete, etc. I suppose I could additionally have a base Device class, then subsequent classes such as Server/Switch/etc. which inherit from that.
My question then is how is this more efficient? Each time the page loads I am still going to have to generate each instance of Device and then populate it from the Database, why I don't really see how this is better than the current implementation.
Thanks for any insight!
Using OOP is mostly unrelated to performance or efficiency. However, it allows you to organize your code in a modular fashion, and encourage code reuse.
A better webpage to explain can be found here.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I have been developing a program for the visualization of some data. My program takes specific input from a MySQL database and draws some graphs (libchart library), creates some tables etc.
My problem is that right now its a code hell in there. I have around 7 php files (index, graph-page, gallery, etc) with HTML/CSS and PHP/SQL code all together (some of them just have the php extension but have only HTML inside). I have no problem to read and understand the project for the time being, but I guess if someone else tried to, he might get a headache. Plus, continuing programming like this is not practical because the project might not be easily scalable in the future.
Do you have any suggestion on how to successfully seperate HTML/CSS from PHP/SQL? I don't want to use a framework since I'm not doing anything that requires user-input, session handling, etc. I just run some queries and visualize the results. I'm mostly talking about architecture here, and if applicable perhaps a script to help me (I've read about Smarty but I'm not sure if that's what I need).
Do you have any suggestion on how to successfully seperate HTML/CSS from PHP/SQL?
Congrats for looking how you can improve code. That's the precondition, you need to want to improve it and the topic is lengthy. So your will is crucial.
I start lightly and then try to give some tips. As you're missing experience, look for one point to start with, most certainly the last one of the list below. But first things first:
To separate something from each other, you need to have some code that separates:
[HTML/CSS/PHP/SQL]
[HTML/CSS] <--> [SEPARATOR] <--> [PHP/SQL]
The Separator here actually is PHP code as well, but I think you get the idea.
As you can see only the Separator talks with HTML/CSS and PHP/SQL.
So both HTML/CSS and PHP/SQL need to have an interface with Separator (the line between) to make this work.
Normally in a program you pass around data that get's processed. The data is pretty dynamic and can have a compound complexity, especially if you pass data to an output routine that should format it properly.
There are multiple ways of how such a Separator (or multiple of them) can be written. You can layer your software or provide components that do things in their area or domain. E.g. you have a database layer or database component that takes care about the interaction with the database.
Or you have a templating engine that takes care to put your strings and arrays into some readable HTML.
In short this is the pasta theory of software design:
Spaghetti code - all in one, code is heavily interwoven, preferable with Bolognese or Aglio, Olio e Peperoncino.
Lasagne code - Layered, one layer has two other layers it interacts with (unless bottom or top), always with Béchamel sauce.
Tortelini code - Small components that just do their job, they have Meat or Spicy Vegetables inside.
Like we eat different pasta in our lives, when programming we need to deal with all these different type of code as well, and we develop our own preferred taste over time. As a kid we're feed but over time we start to cook something our own and vary the recipes.
So I think it's a good point you just don't want to now eat MVC Framework X with much awesome for the next weeks only because somebody told you it's the way to eat now. And before eating, there is tasting, right? Not to mention fast-food, you know like these noodles with sauce in package - only add water. Urgh.
I don't know which data your output needs and what the input is. Following are some rough refactoring tips for applications that output HTML/CSS and interact with a MySQL database. This can not be a complete list and the descriptions can only roughly outline some thoughts:
Move CSS out of HTML. Use selectors effectively in the linked CSS definition and replace any style attributes if you still have some. This makes your CSS code re-useable and more modular. It will help you to find flaws inside your HTML and to separate the Structure (HTML) from the Presentation (CSS). Effective HTML start with effective usage of CSS, those two are very powerful together and often this already will lighten your programs output routines.
Move business logic out of HTML. Both HTML and your code can be a beast, so better keep them apart. They have the tendency to fight with each other, and as both are very powerful, the fight will continue while you develop your application, that distracts you from the work you need to do.
Consider if you need to already have complex output inside your application or if you can just pass on arrays with subelements (a key is a var, a var can contain a string or number or another var-array). Normally that is all needed to pass even complex data into a view or template. You HTML then only needs to echo some array members and or foreach over subarrays. This is a very simple technique to create a template. You can use PHP for it, so you're actually really flexible (just draw the border which code belongs into your view layer and which is part of the application, e.g. providing values for the view).
Move SQL out of your code. Move the database interaction code away. Create yourself one or multiple objects that have methods which return the data in a way you need (consume) it in your actual processing code, like $component->getThatData() which then returns data in a normalized form. Make those components then use a dedicated database component to talk over with the database. In your application code (business logic) only use the database component and preferably the objects you create to get the data, so you don't have any line of SQL any longer inside your main code.
Divide and Conquer your application code: Divide your code into Transaction Scripts. They are often easy to create from existing spaghetti code and will be probably become the said Separator you're looking for in middle terms. They will then have the role to process data and passing it on (into the output/view).
Use clear language: If you have complex formatted string data that is not normalized, write yourself Parser classes that do the work for you and which can be easily re-used (if that's the case in your application). As you should look forward to minimize the use of plain SQL in your code, you should also look forward to move complex regular expressions away as well. Encapsulate what varies is a key point. Same applies to long routines to just handle some data (e.g. sort, order and arange it in another format), move them into components of each own and think about how you can make them accessible and re-useable.
Make your code functioning: Find out about the logic how you invoke functionality in your program. You can try to separate functionality away from how it's invoked. E.g. some routine that invokes any of the Transaction Scripts. This might not be necessary if you request PHP files directly via the browser, as those are then your transaction scripts and the webserver takes care to resolve the command send via URL into your application to the transaction script. But you should then wrap any logic needed to process the incoming command and it's parameters into re-useable components (e.g. a Request class that contains standard code to get the URL and or variables from a HTTP request).
Create a common entry-point by including the same file at the very top of all files that are called via the browser. You can then put common code (like setting up the application session state object and initializing the database component) into it, see as well Application Controller
Remove duplication by looking for literally duplicated code. Wrap it into a function or class. Create a library folder for your own application into which you put your includes. If you follow a common pattern with Classnames and Namespacing, you can easily use an autoloader to keep inclusion easy. Make your library apart from third-party code. Place all third-party code into a library folder of it's own with one subdirectory for each third-party component.
Use lightweight, existing components. Lightweight is important because you have your own code already, you don't want to turn and press it all at once onto a framework.
Existing is important because you don't want to re-invent the wheel. You will have enough work for your own refactoring your code. After you feel better about your application and you still have power and will, you can always write everything new. But if you're alone or in a small team, Existing is pretty powerful.
Simple libraries are for example:
Templating engine: Mustache
Database layer: NotORM
Create Application State, e.g. as an object you can make use of in case some components need to know about the application state or each other without direct interaction. By default in PHP if you don't have one, global and global static variables are used to create state. However these variables can make your live hard as code grows. When you create an application state object, it's clear which components make use of it, access to it can be controlled (e.g. calling a method instead of reading a variable, which can help with debugging) and components as well can find out if it's the right time in the application flow to come into action. It's also a good tool for refactoring your code over time.
Preserve a Working Application, keep your code in a state to run. Ideally this would be backed up by automatic tests. Consider that you need to rewrite much. For example if you start to integrate a database component, do it. Move all your existing code to it in one step. So who tells you it still runs? Use git for better undo and to test stuff. That's more important than choosing the right library. Preserving a working application is also always the key point because that's why you change it, right?
Why not use a templating engine? TWIG is very easy to use and great for this sort of thing. It is often used with the Symfony framework, but can easily be used on its own.
as you don't need user input and store session.
You can just create a controller -> model & controller -> view structure
the controller: will help you get data from DB (via. model) and embed data into view.
You can create 3 folders controller, model, and view. In each folder, you can create files based on your needs(e.g.MVC for User).
The model can access static objects written in mysqli.inc.php or pdo.inc.php based on your need you can write a template for connection, query, disconnection, in all your model classes.
In model file, you can call static function DB::query('SELECT/INSERT/UPDATE/DELETE', );
For view, you will need a render function to embed data into HTML Code for example
function render() {
//start output buffering (so we can return the content)
ob_start();
//bring all variables into "local" variables using "variable variable names"
foreach($this->vars as $k => $v) {
$$k = $v;
}
//include view
include($this->file);
$str = ob_get_contents();//get teh entire view.
ob_end_clean();//stop output buffering
return $str;
}
In the controller, you can include your model file call particular class and function for data. Call view file with render function for example,
$view = new view('../view/data.php');
$view->name = 'Your Name';
$view->bio = "I'm a geek.";
echo $view->render();
you can either return or echo your view based on your requirement
Currently we have a lot of web pages that either have SQL statements embedded in them or call a specific php script that does a specific job - ie getNames.php - as part of a ajax call back. Neither are particularly maintainable.
I was thinking about using a REST like API to get the necessary data to the client and then munge the data into something usable. This is attractive as this lessens the burden on maintaining highly complex sql in code and allows centralisation of data (so just one AJAX call to get the data not lots of little ones). Also allows the database to change lessening the impact on the client.
However there are two problems I can see with this strategy:
The site is a game, and so I need the RESTlike API to be protected from abuse/cheating as much as possible.
All examples of REST API's use a controller to handle the requests in root. That's not ideal for me since we are at //company/games/game/ and there already is an index.php at root (//company/).
What options and strategies do I have for the two constraints I listed?
Well, you're asking for opinion, but I'm well seasoned enough (having written many many API schemes over the years) that I'm totally willing to open myself up to Net abuse. I think the key here, and this should provide an opinion to work from on both of your questions, is that REST is simply a set of principles. Sure there are people that follow a RESTful pattern explicitly, but that isn't practical for most people.
Take the Flickr "REST" API for instance... a call may look like this: http://api.flickr.com/services/rest/?method=flickr.favorites.getContext&api_key=a114adf91150953107987e4c3dc14df8&photo_id=6033564557&format=json&nojsoncallback=1&api_sig=0d2c215992d643ef6fe4a085805f7059
Not very RESTful, from a patterning perspective... however, it contains all of the elements of REST and is a fine enough model. You can understand what it is doing at a glance, and you can easily build on top of that.
IN the end, REST is a set of principals, not a protocol, and not even a pattern in and of itself. You're free to implement it however you want. There's always an interoperability intermediate layer and the point is to just make it understandable... and many of the REST patterns actually get in the way of that, favoring form over function.
In fact, most of the patterns I've seen are insufficient for anything particularly advanced, but that's part of the point of REST... Keep It Simple (Stupid).
I Often ask this question to myself again and again. what is the use of encapsulating the data in PHP. although i do understand it's usage and usefulness of hiding the data or design implementation of an application from Public. i do agree this way i could achieve lots of security by not allowing other developers to see how i implemented other methods. now in case of PHP i still have some unanswered questions.
a) How does encapsulating data in PHP
gonna help me because as PHP does not
provide any encryption system (i know
there exist few but i am talking in
general) which will encrypt my source
code from being read by others, anyone
can always comeback see my source and
modify accordingly breaking the rules.
now this lays down the whole purpose
of data encapsulation isn't it?
Now there may be different situation i may have to handle using PHP let me take into consideration two scenarios where i have two deal according to the situation.
SITUATION A :
A Clients wants me to develop a Web
Application, Which will be stored
locally into his desktop machine and
accessed from there. in the context of
this situation i can do nothing to
make sure no one touches the source
code. Encapsulating the data is of no
use here i see. isn't it?
Situation B:
I need to develop a Web Application
which will be hosted in server and
accessed from there, and i have
defined several class which is bounded
by encapsulation, but i want other
developers to extend the class by
making use of Public API. i really do
not have any idea on how i can allow
anyone(developers) to extend using my
class in this situation? i am really
not sure on how public API things
work?? i will be grateful if someone
could put some light on the logic
behind implementing PUBLIC API. and is
this where Data Encapsulation comes
into picture? is this the only
situation where i will badly need
encapsulation to be implemented
within my application?
Thank you.
You do not use Encapsulation because it prevents people from touching your code but because you want to create a limited but dedicated public API for your objects to exchange messages through. This a key element in in OOP paradigm. The aim is not to security but maintainable and flexible applications. If people want to modify your code, let them. They are grown ups.
I believe you are mixing conepts here. One thing is the design principle of data encapsulation, another concept is the availability of the source code or reverse engineering.
Data encapsulation is important to your development team. Its advantages are the fact that code is more reusable thanks to the clear interfaces and the code is more easy to read and understand because data are logically separated.
This has nothing to do with code availability and possibility to reverse engineer your code. Even if data are encapsulated, your code can still be viewed and analyzed.
Those concepts meet when you are publishing a closed source library. You want to make sure that it has a clear public API, provided as an interface, and you want to make sure it is encrypted so nobody can copy its internals.