I am coming from java background which has rich threading framework. In the past , I kept hearing that PHP does not support threading.
But below code from this site creates the thread in PHP in almost same way as java does.
So what's the difference ?
<?php
class ChildThread extends Thread {
public $data;
public function run() {
/* Do some work */
$this->data = 'result';
}
}
$thread = new ChildThread();
Also I read below statements on google
Avoid the idea of running paralell tasks (threads or processes) in
PHP. It has some modules for this purpose, but they are not available
on every platform and are not part of the PHP core, so the chances for
you to be able to use them are very low.
This way wil not will work in every single environment
So My question above way of creating thread thread does not work on every platform(which platform for example) ? Does it mean there is no true
way of creating thread that works on all environment ?
Related
I've been using this method for years, and I've never run into an issue; however, it's always sort of nagged at me as to whether or not this is good practice. I'll cover what I'm doing specifically first and then provide background to the reasoning after since I'm sure it will be questioned.
Problem / Question
I am using file_get_contents to retrieve the contents of the very script that is running. In essence:
<?php
/**
* My PHP Script On Load
* Version: 1.0.0
*/
class MyClass {
public function __construct() {
$matches = array();
if (preg_match('Version\: ([0-9\.]+)/s', file_get_contents(__FILE__), $matches)) {
$version = $matches[1];
}
}
}
$class = new MyClass();
The above works, and out of thousands of page loads of my own use (and many tens of thousands of never hearing of errors that could stem from this), I've never had a problem doing this. I've just always wondered if either a) it's bad practice, or b) it has the possibility of causing an error.
Background / Use-case
Naturally the first question is going to be "Why don't you just put the version in the constructor?" Of course, I could, but I must have the plugin version at the top of the file in the comments as shown and the only reason I don't do that is so I don't have the possibility of forgetting to update one or the other. By having it one place, I never have to worry about a screw up, which if it made it to a release build, could cause major problems with the update system of the platform I'm working on.
I'm open to other ideas for how to approach this, aside from using a deployment/CI to automate the placement of the version number, which I've already considered and may implement at some point. But three things must be true: 1) the version must be commented out at the top of the file in the same format shown in the example, 2) I must be able to have version available to the PHP code within the very same file, 3) the class must be instantiated from within the same file.
There is a PHP function to retrieve just the comments: ReflectionClass::getDocComment. You can use it instead of reading the whole file. I'm not sure about how it works when the code is encoded as mentioned by #Iłya Bursov.
<?php
/**
* My PHP Script On Load
* Version: 1.0.0
*/
class MyClass {
public function __construct() {
$matches = array();
if (preg_match('/Version\: ([0-9\.]+)/s', (new ReflectionClass(__CLASS__))->getDocComment(), $matches)) {
$version = $matches[1];
}
}
}
$class = new MyClass();
?>
As soon as it is open ended question, just some thoughts:
for some projects php files must be encoded, for example with zend guard, this will break this scheme completely
reading whole file is not ideal, you can just read first 100-200 bytes of it instead
what about pre-processing before you upload to server? some script, which reads all files, comments and puts variable $version into class?
I have a function, which someone else wrote, that creates a cURL wrapper object inside the function. Simplified version below
public function getCodes()
{
//do some stufff
$communicator = new Communicator();
$result = $communicator->call($this->API_KEY);
//do some stuff with $result
}
I was tasked with learning PHPUnit and writing tests for this type of code. In doing so I found that it's really hard to test a function like this when the object is created inside of the function and also that tests shouldn't require any outside communication to work.
We wanted to push our tests to git as many projects do but we didn't want to accidentally or intentionally push our API credentials to git.
So my solution was to keep getCodes() public but make it a wrapper for a private function that accepts a Communicator object as a parameter. Then I could test the private method with a mock Communicator object.
But this would mean that getCodes is never tested (my boss wants 100% code coverage) and I also read that you shouldn't be writing tests for private functions in most circumstances.
So my question is basically, how do I write a test for a function like this with an API call.
I would really suggest rewriting the code to inject the Communicator object via constructor.
If you already see there is a big issue with writing tests for something it is a very strong signal to re-thing the current implementation.
Another thing is that you shouldn't test your privates. Sebastian Bergmann wrote a post on his blog about this some time ago and the conclusion is - it is possible just not good (https://sebastian-bergmann.de/archives/881-Testing-Your-Privates.html).
Completely different thing is that I think your tests shouldn't go outside of the boundaries of your system. That is - mock everything that connects to outside systems. Such tests may fail for various of reasons non of witch are valid from the sole perspective of running tests.
You also mentioned coverage. Unfortunately this is something where, I hope, everyone will agree - you cannot have it the moment you start using native PHP resources (with some small exception like FS). You have to understand that things like curl, ssh, ftp and so on cannot be unit tested.
I come from the C++ world.
And recently, I started using Apache Thrift, the RPC framework. I am writing PHP client code and Python server code.
When I am reading the PHP implementation, I find the following:
class TStringFuncFactory {
private static $_instance;
/**
* Get the Singleton instance of TStringFunc implementation that is
* compatible with the current system's mbstring.func_overload settings.
*
* #return TStringFunc
*/
public static function create() {
if(!self::$_instance) {
self::_setInstance();
}
return self::$_instance;
}
....
}
It is the singleton WITHOUT locks.
Question
What is the processing pattern of PHP? Does it guarantee that this won't happen risk condition.
+1 #N.B.
PHP (cli or http) exists as a single thread on a single cpu core unless you do some real work to make your application multithreaded.
How can one use multi threading in PHP applications
For the HTTP side, each PHP execution lives and dies with the request cycle. The server may process several requests concurrently, which would result in several concurrent PHP executions, but each is entirely independent from the next.
So basically this is a non-issue. For all intents and purposes checking the static data member satisfies the singleton pattern.
Does the below code show an acceptable way to cache both fully built pages and database queries?
The caching of built pages is started with the __construct in the controller and then finished with the __destruct, in this example all pages are cached for a default of 15 minutes to a file.
The query caching is done with apc and they are stored in memory for the specified amount of time per query. In the actual site there would be another class for the apc cache so that it could be changed if required.
My aim was to build the most simple possible mvc, have I failed or am I on the right sort of track?
Controller
//config
//autoloader
//initialiser -
class controller {
var $cacheUrl;
function __construct(){
$cacheBuiltPage = new cache();
$this->cacheUrl = $cacheBuiltPage->startFullCache();
}
function __destruct(){
$cacheBuiltPage = new cache();
$cacheBuiltPage->endFullCache($this->cacheUrl);
}
}
class forumcontroller extends controller{
function buildForumThread(){
$threadOb = new thread();
$threadTitle = $threadOb->getTitle($data['id']);
require 'thread.php';
}
}
Model
class thread extends model{
public function getTitle($threadId){
$core = Connect::getInstance();
$data = $core->dbh->selectQuery("SELECT title FROM table WHERE id = 1");
return $data;
}
}
Database
class database {
public $dbh;
private static $dsn = "mysql:host=localhost;dbname=";
private static $user = "";
private static $pass = '';
private static $instance;
private function __construct () {
$this->dbh = new PDO(self::$dsn, self::$user, self::$pass);
}
public static function getInstance(){
if(!isset(self::$instance)){
$object = __CLASS__;
self::$instance = new $object;
}
return self::$instance;
}
public function selectQuery($sql, $time = 0) {
$key = md5('query'.$sql);
if(($data = apc_fetch($key)) === false) {
$stmt = $this->dbh->query($sql);
$data = $stmt->fetchAll();
apc_store($key, $data, $time);
}
return $data;
}
}
Cache
class cache{
var url;
public function startFullCache(){
$this->url = 'cache/'.md5($_SERVER['PHP_SELF'].$_SERVER['QUERY_STRING']);
if((#filesize($this->url) > 1) && (time() - filectime($this->url)) < (60 * 15)){
readfile($this->url);
exit;
}
ob_start();
return $this->url;
}
public function endFullCache($cacheUrl){
$output = ob_get_contents();
ob_end_clean();
$output = sanitize_output($output);
file_put_contents($cacheUrl, $output);
echo $output;
flush();
}
}
View
<html>
<head>
<title><?=$threadTitle[0]?> Thread - Website</title>
</head>
<body>
<h1><?=$threadTitle[0]?> Thread</h1>
</body>
</html>
"Outsource" the caching
First of all, you have to understand that caching of GET request is usually done all over the internet. Especially if your user is connecting via some kind of proxy.
And then there is also ability to set long expire time, so that user's browser does the caching of the HTML page and/or the media files.
For starting to look into this, you should read these two articles.
What is your goal?
Before you begin attempting to add cache, make sure that you actually need it. Do some benchmarking and look into what are your bottlenecks. Optimization for sake of optimizing is pointless and often harmful.
If you KNOW (and have data to back it up .. it's not about "feeling") that your application is making too many SQL queries, instead of jumping to query caching, you should begin by examining, what are those queries for.
For example:If you see, that you are performing slow query each page-view just to generate a tag cloud, you instead should store the already completed tag cloud (as HTML fragment) and update it only, when something has changed.
Also, "add cache" should never be your first step, when trying to improve performance. If your queries are slow, use EXPLAIN to see if they are using indexes properly. Make sure that you are not querying same data multiple times. And also see, if queries actually make sense.
This is not MVC
I am not sure, where did you learn to write this way, but you seem to be missing the whole point of MVC:
"view" is not a template
"model" is not a database abstraction
"controller" is not application logic
You also seem to be missing the meaning for the word "layer". It is NOT a synonym for "class". Layers are groups of reusable components that are reusable in similar circumstances [1].
You might benefit from reading this and this post. They should help you understand the basic of this architectural pattern.
Where to cache in MVC architecture?
There are basically two points at which you can do the caching, when working with MVC (or MVC-inspired) architecture: views and persistence logic.
Caching for views would mostly entail reuse of once rendered templates (each view in MVC would be juggling multiple templates and associated UI logic). See the example with tag cloud earlier.
The caching in persistence logic would depend on your implementation.
You can cache the data, that is supposed to be passed to the domain objects, withing services:
Note: in real application the new instances would not be here. Instead you would be using some factories
$user = new User;
$user->setId( 42 );
$cache = new Cache;
if ( !$cache->fetch( $user ))
{
$mapper = new UserMappper;
$mapper->fetch( $user );
}
$user->setStatus( User::STATUS_BANNED );
$cache->store( $user );
$mapper->store( $user );
// User instance has been populated with data
The other point for cache would be Repositories and/or Identity maps, if you expand the persistence layer beyond use of simple mapper. That would be too hard explain in with a simple code example. Instead you should read Patterns of Enterprise Application Architecture book.
.. some other bad practices in your code:
Please stop using singletons for establishing DB connection. It makes impossible to write unit tests and causes tight coupling to specific name of a class. I would recommend to instead use this approach and inject the DB connection in classes, that require it.
Also, if your query has no parameters, there is no point in preparing it. Prepared statement are for passing data to SQL .. but none of your example has any parameters.
This issue arises mostly because of your magical Database class. Instead you should separate the persistence logic in multiple data mappers. This way you would not be face with self-inflicted problem of having single method for all queries.
The var keyword is an artifact of PHP4. Nowadays we use public, private and protected.
You are hard coding the connection details in your code. It is basically a violation of OCP (the dumbed-down version: here).
Update
Is this an acceptable way to cache both queries and built pages in a PHP mvc?
The caching of built pages is started with the __construct in the controller and then finished with the __destruct, in this example all pages are cached for a default of 15 minutes to a file.
The destructor will be called when the all references are freed, or when the script terminates. I assume this means when the script terminates properly. I would say that critical exceptions would not guarantee the destructor to be called.
for example
class A
{
public function __construct()
{
echo "Construct\n";
}
public function __destruct()
{
echo "Destruct\n";
}
}
test code:
$test = new A();
die( "Dead\n"); // Will output Construct; dead; Destruct
$test = new A();
throw new Exception("Blah\n"); // Construct, Fatal error (no destruct)
$test = new A();
require_once( 'invalid_file.php'); // Construct, Fatal error (no destruct)
You'd better use register_shutdown_function() to go for sure. but be careful
Multiple calls to register_shutdown_function() can be made, and each will be called in the same order as they were registered. If you call exit() within one registered shutdown function, processing will stop completely and no other registered shutdown functions will be called." There's no guarantee that your shutdown function will be called if some other shutdown function runs before yours.
IMHO, you are reinventing the wheels there is a lot of frameworks already. do you want a simple and small one ? well there is Silex
which is built from the same guy who created Symfony. trust me you will waste your time.
or why not try using Laravel you can choose only the packages you want not all the framework
they already have a well designed caching system see http://laravel.com/docs/cache
To understand how caching is done right in MVC style Symfony 2's documentation has a very good explanation
Also read this question Caching strategies in MVC Framework
In terms of how necessary any of this is; it really depends on your situation. In my experience, unless you're expecting large numbers of users (say, more than a few dozen on your site at the same time), you don't need caching. A site like StackOverflow, on the other hand, would not be able to function without a very well thought out caching strategy.
How would you create a build function to cache the entire built page?
as i understood from your question you want to cache the entire page ?
How would you create a build function to cache the entire built page?
you can simply use output buffering to achieve this.
an example is that you have index.php code:
<?php
ob_start();
// All your mvc and application logic here
$output = ob_get_contents();
ob_end_clean();
the entire page output between ob_start() and ob_get_contents() is now captured in $output
you can save it in a file and do what ever you want
you can read more about ob_get_contents() in PHP Website
It all depends on where your performance problems lie. If they are within your DB queries, then cache those - but of course your controller needs to be prepared for dirty data.
If you were to cache stuff at the controller layer, then that will perform better, but you'll probably have more stuff to cache (your DB data is going to be smaller than your HTML). Then of course the user will need to be prepared for seeing dirty data.
Unfortunately you can't really have any hard and fast rules because each solution has different requirements. My advice is to only start caching data when you really need to. Have a close look at where your performance bottlenecks are and do your caching appropriately, and make sure you can scale outwards (more machines) not just upwards (increasing spec of machine).
I add to what CodingInsane have posted!
He is right this way you can easily make your own little cache Mechanism.
just write the content of $output (in the CodingInsane post) to a file like: the_file.php.cache
and next time in the the_file.php read the content of the_file.php.cache and display it the user and exit.
However any cache mechanism needs a way to update (rebuild the page). To do so you just have to keep track if the content has changed or check the last time the content has changed and compare it with the last time the the_file.php.cache has been modified filemtime().
Good Luck!
I am new to PHP, and working on a class based web site. So my question is simple. Can I compile the site like I can in .NET?
This would be helpful to me because I changed my IsAAction interface to accept an error callback function as a parameter of the Execute function, and I would like all of my implementations to break so I can easily see where to change them.
Thanks in advance.
PHP can be compiled, as in you can compile it to machine code and prevent a parsing everytime you access a file. That the way accelerator like APC work. But you can't compile it like a .NET DLL with every error checked in advance. It would go against its dynamic nature. Late binding mean it will always check for error at runtime
For your particuliar problem, I would suggest adding Unit Tests to your project. They are very good to have anyway, and they will help you catch error in your interface implementation. I personally couldn't live without them. You may want to check PHPUnit or SimpleTests.
EDIT To understand why PHP can't check your error, just check this snippet of code.
if ($_GET['impl'] == 'interface1') {
interface MyInterface {
function foo($var);
}
} else {
interface MyInterface {
function bar($var, $var2);
}
}
class Implementation implements MyInterface { //Will crash or not depending on the URL!
function foo($var) {}
}
Yes and no. See:
Can you "compile" PHP code?
And:
http://www.phpcompiler.org/
And:
http://www.scriptol.com/apollo.php
https://github.com/facebook/hiphop-php/wiki - although I'm sure there are other answers on here that you'd find useful.
There's a opened topic on stackoverflow that is related.
Can you “compile” PHP code?
Some parties such as Facebook rewrote PHP runtime, or part of it so they make it possible to run compiled php code or other source codes, pretty much whatever you like.
HipHop for PHP
Its not an easy task. But you can do it.
Not to my knowledge. PHP is a script language.