3

So I'm using pthreads for async writing to MongoDB (I wanted to try React but it doesnt support PUT and POST HTTP methods) but I encounterd a problem when using the Thread class. For some reason, when I put code inside the __construct() and run() methods, executing it gives an error that certain classes aren't found. I'm using the same Composer autoloader and have no problems when I'm not using the Threading API. Any ideas as to why it is happening?

<?php

class WriterThread extends Thread
{
    private $validator;
    private $pathResolver;
    private $fileUpload;
    private $fileSystem;
    public $result;
  public function __construct($folderPath, $mongoFS)
  {
      try {

      $this->validator = new MongoFileSystemValidator(1024 * 1024 * 1024 * 2); //the maximum size set to 2GB
        // Simple path resolver, where uploads will be put
        $this->pathResolver = new FileUpload\PathResolver\Simple($folderPath);
        // The machine's filesystem
        $this->fileSystem = new MongoFS($mongoFS);

        // FileUploader itself

        $this->fileUpload = new FileUpload\FileUpload($_FILES['files'], $_SERVER);
        //var_dump(get_declared_classes());
        $this->fileUpload->setPathResolver($this->pathResolver);
        $this->fileUpload->setFileSystem($this->fileSystem);
        $this->fileUpload->addValidator($this->validator);
      } catch (Exception $e) {
          echo $e->getMessage();
      }

  }
  public function run()
  {
      $this->result = $this->fileUpload->processAll();
  }
}

So PHP outputs an error stating that a class definition of one of the class instances I'm using inside the thread is not found when it's supposed to be loaded. And If I manually import it with include or require, The code outputs another error stating that I'm trying to access a method of a non-object type variable.

2
  • whats the exact error message Commented Dec 22, 2013 at 20:18
  • Fatal error: Class 'FileUpload\File' not found in <b>\vendor\gargron\fileupload\src\FileUpload\FileUpload.php</b> on line <b>257 . And this library is loaded with Composer autoloader but still, PHP outputs this. Commented Dec 22, 2013 at 20:21

1 Answer 1

7

When you are writing a pthreads application the class, function and constant table are by default inherited when you create a thread. However, the SPL autoloading mechanism, since it is implemented strangely - half in core and half out - must be reset as there is no sane way to manipulate it from within the pthreads extension.

The solution is to include your autoloading code in ::run, usually vendor/autoload.php, you should know the path to this code for your application.

TLDR; the class table is available, the autoloader is not, include it ...

In addition to the autoloader problem, the construction of that object is not sane, read: https://gist.github.com/krakjoe/6437782

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the answer. The article is really good but it doesn't appear on pthreads.org. I read it, but still, can you please be more specific about what exactly isn't right in the class definition?
You are responsible for retaining references to objects you pass into a thread, by constructing objects in the constructor you are not allowing yourself to retain the reference you require for safe operation, see the segfault bit ...
So I should never instanciate objects inside the Thread class but pass already instanciated ones as arguments of the ::__construct? And this is done because since pthreads doesn't make a new reference(reference count? correct me please), there are 0 references(then are the variables containing null instead of a reference to an object?) and PHP garbage collector calls::__destruct and destroys the references?
That's pretty much the long and short of it, yeah.
I tried copying the loader code into my run method, however it didn't work. However this is running from "within" a PHAR, would that affect this differently (e.g. not having a reference to the PHAR in the URL so it can't locate the file)?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.