Cphalcon: Custom Defined Function

Created on 10 Sep 2019  路  21Comments  路  Source: phalcon/cphalcon

Not sure if this is a bug in v2.0.13 or I'm doing something wrong here... I was trying to define simple test functon in Di and then reuse it in any Controller with $this->test('text'). All this does is just keeps loading the page continuesly and then hangs my system.

In my /app/config/bootstrap.php I have this;

$di->set('test', function($text) {
  return exit($text);
});

In my /app/controllers/Index.php I have this;

function index() {
  $this->test('testing');
}

What am I doing wrong here? or is this a bug!?

bug low

All 21 comments

Is /app/controllers/Index.php a controller? Is your class extending the controller or at least the Phalcon\Di\Injectable? If not you do not have access to DI services as properties.

Here is a short version of my code; Between I have tried same code in v4-beta2, exactly same result. It loads the file for a while then hangs my system for a bit and text is not shown. If I use $this->test('text') inside my Base.php it shows blank page no text, but at least no long loading and system hangs. When I try accessing it inside Index.php with $mytest = \Phalcon\Di::getDefault()->get('test'); $mytest->test('text'); it works exactly like in Base.php only shows blank page no text.

My /app/config/boostrap.php

use Phalcon\Loader;
use Phalcon\DI\FactoryDefault;

$ld = new Loader();
$di = new FactoryDefault();

$ld->registerNamespaces([
  'App\Controllers' => '../app/controllers/',
])->register();

$di->set('test', function($test) {
  return exit($text);
});

My /app/controllers/Base.php

namespace App\Controllers;

use Phalcon\Mvc\Controller;

class Base extends Controller {

}

My /app/controllers/Index.php

namespace App\Controllers;

class Index extends Base {

  function index() {
    $this->test('text');
  }

}

So it was a bug :-) Good to know! Thank you!

@v00v It looks like a bug ;) We need to investigate a bit more but will try to do that before the next release

@v00v Could you try returning something instead of using exit()?
I do see an issue when using exit() in this closure (causing segfault) but don't think this a case that is ever used in an application.
If you don't exit it looks like it's working fine.

@ruudboon I did try returning something, but it didn't work. But I'll try again today and report back.

@v00v Please let me know. See also this test: https://github.com/phalcon/cphalcon/pull/14385/files The exit() issue is probably something I'm gonna report to Zephir but don't think it's your main problem.

@ruudboon Yes simply returning something works.

From boostrap.php

$text = "Hello World";
$di->set('test', function() use ($text) {
    return $text;
});

From /app/controllers/Index.php

function index() {
  print_r( $this->di->get('test') );
}

@v00v Then I would like to close this issue. And track the problem in Zephir (https://github.com/phalcon/zephir/issues/1912).

But doing something like this, just shows blank page no output.

From bootstrap.php

$di->set('test', function() {
    $text = 'Hello World';
    return print_r($text, 1);
});

From Index.php

function index() {
  $this->di->get('test');
}

It only works when print_r() is used in Index.php and not in bootstrap.

@v00v Can you check your error_log?
Can you try

$di->set('test', function() {
    $text = 'Hello World';
    return print_r($text, true); //should be a boolean
});

@ruudboon Same thing, just blank page and no errors/warnings. But if I use print_r( $this->di->get('test') ) inside Index.php it works, and it doesn't matter if print_r() is in boostrap.php

@v00v Could there be more things going on in your code?
This test passes:

$di->set('closure2', function () {
       $text = 'Hello World';
       return print_r($text, true);
});
$I->assertEquals( "Hello World", $di->get('closure2'));

But something like this works :-) LOL

In boostrap.php

function mytest() {
    return print_r('Hello World');
} #mytest

$di->set('test', function() {
    return mytest();
});

In Index.php

$this->di->get('test');

Note this time without print_r() in Index.php

You're still on v4-beta2?

Okay sooo print_r() works like this :-)

$di->set('test', function() {
    return print_r('Hello World');
});

and yes v4-beta2

But if you try to define, FALSE it will still work, same with TRUE (but wont show anything). only print_r() by it self works. And of course you already know about how exit() behaves ^_^

The second parameter is for returning. Not sure where you do this but you should output it.

$di->set('test', function() {
    $text = 'Hello World';
    return print_r($text, true);
});
echo $this->di->get('test');

Or when you're in a controller you want to pass it to your view

Okay, I got this working how I needed it to.

In custom library /app/libraries/Lib.php

<?php
namespace App\Libraries;
class Lib {
  function test($text) {
    return print_r($text);
  }
}

In bootstrap file /app/config/boostrap.php

use Phalcon\Loader;
$ld = new Loader();
$ld->registerNamespaces([
    'App\Libraries' => '../app/libraries/',
])->register();
use App\Libraries\Lib;
$di->set('lib', function() {
    return new Lib();
});

Then in controller file /app/controllers/Index.php

<?php
namespace App\Controllers;
class Index extends Base {
  function index() {
    $this->lib->test('Hello World');
  }
}

I think the main problem is with exit() function cannot be used inside $di->set this is when system hang happens. Everything else seems to work as expected.

Using exit() inside a closure is an issue this is tracked in Zephir (https://github.com/phalcon/zephir/issues/1912)

Thank you for submitting bug to Zephir and for your help!

Was this page helpful?
0 / 5 - 0 ratings