1. The forums will be archived and moved to a read only mode in about 2 weeks (mid march).

[Solved] Serialization of Closure not allowed

Discussion in 'Development' started by Sandertv, Mar 24, 2017.

  1. Sandertv

    Sandertv Zombie Pigman Poggit Reviewer

    Messages:
    786
    GitHub:
    Sandertv
    Hello!
    So I was working on a plugin, when I came past a weird error that I couldn't really place. Here's the exact error:
    Code:
    Exception: "Serialization of 'Closure' is not allowed" (EXCEPTION) in "myzip:///plugins/BlockSniper-betterBrush (4).zip#BlockSniper-betterBrush/src/Sandertv/BlockSniper/brush/BrushManager" at line 74                                                                                  
    The part of code where that appeared in is here:
    PHP:
    public function storeBrushesToFile() {
      
    $data = [];
      
    var_dump(self::$brush);
      foreach(
    self::$brush as $playerName => $brush) {
        
    var_dump($brush);
        
    $data[$playerName] = serialize($brush);
      }
      
    yaml_emit_file($this->getPlugin()->getDataFolder() . "brushes.yml"$data);
    }
    Now as you can see, I already var_dumped some of the lines, to make sure it actually is an object I'm trying to serialize, which it is. I searched the internet and found that it's usually an issue with trying to serialize functions, but that's not what I'm doing, am I?

    The whole plugin can be found here: https://github.com/BlockHorizons/BlockSniper/tree/betterBrush
    Thanks in advance!
     
  2. Muqsit

    Muqsit Chicken

    Messages:
    1,548
    GitHub:
    muqsit
    It because you can't serialize \pocketmine\Server[citation needed]. Brush.php requires second argument to be \pocketmine\Server. You should drop the second argument and use
    PHP:
    $this->server = \pocketmine\Server::getInstance();
    instead, in Brush.php's constructor.
     
    SOFe and Sandertv like this.
  3. Sandertv

    Sandertv Zombie Pigman Poggit Reviewer

    Messages:
    786
    GitHub:
    Sandertv
    I see, thanks.
     
  4. Sandertv

    Sandertv Zombie Pigman Poggit Reviewer

    Messages:
    786
    GitHub:
    Sandertv
    I just tried what you suggested, but that didn't work either. Any more ideas?
     
  5. Muqsit

    Muqsit Chicken

    Messages:
    1,548
    GitHub:
    muqsit
    Can you send the output of var_dump on self::$brush?
     
  6. Sandertv

    Sandertv Zombie Pigman Poggit Reviewer

    Messages:
    786
    GitHub:
    Sandertv
  7. Muqsit

    Muqsit Chicken

    Messages:
    1,548
    GitHub:
    muqsit
    Hmm that error shouldn't exist then. Try using json_encode, json_decode(..., true) instead.
     
    Sandertv likes this.
  8. dktapps

    dktapps Administrator Staff Member PMMP Team

    Messages:
    774
    GitHub:
    dktapps
    You should be aware that closures are considered objects by the PHP core.
     
  9. dktapps

    dktapps Administrator Staff Member PMMP Team

    Messages:
    774
    GitHub:
    dktapps
    Having looked at the code, my observations are these:

    You might want to consider implementing the JsonSerializable interface so that you can select which properties you want to serialize.

    JSON_FORCE_OBJECT simply causes output JSON arrays to be serialized as JSON objects instead of JSON arrays. This means that the `[]` syntax is not used in the output and every offset that would normally have a numeric index will have a string index instead containing that number.

    Code:
    [
        "somedata",
        "somemoredata",
        "somemooaaaaardata"
    ]
    
    vs
    Code:
    {
        "0": "somedata",
        "1": "somemoredata",
        "2": "somemooaaaaardata"
    }
    
     
  10. Sandertv

    Sandertv Zombie Pigman Poggit Reviewer

    Messages:
    786
    GitHub:
    Sandertv
    I'm not a Json expert, so I didn't know :p Thanks. I'll give it a try.

    I am still curious about what causes it though. Any ideas?
     
    Last edited: Mar 24, 2017
  11. dktapps

    dktapps Administrator Staff Member PMMP Team

    Messages:
    774
    GitHub:
    dktapps
    Most likely because you attempted to serialize a Block object, which holds a reference to a Level, which holds a ref to Server, and whatever else Server has a ref to, directly or indirectly...

    you need to be very careful of leaks when referencing things. you can hold a reference to something that seems perfectly fine, like a Block, but leaks a whole bunch of other things that it references. For example when that Block's Level is unloaded, it's going to be leaked because things still reference things that still reference it.
     
    Last edited: Mar 24, 2017
  12. Sandertv

    Sandertv Zombie Pigman Poggit Reviewer

    Messages:
    786
    GitHub:
    Sandertv
    That must be it. It does hold a block reference. Thanks!
     
    Muqsit likes this.
  13. Sandertv

    Sandertv Zombie Pigman Poggit Reviewer

    Messages:
    786
    GitHub:
    Sandertv
    I made the Brush class process the input blocks at the output, so that it doesn't hold any Block references, and it worked! Thanks @Muqsit and @dktapps for your help. I really appreciate it.
     
    dktapps and Muqsit like this.
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.