We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

APi Rest

Hello, I need some help. I am building an API with phalcon and it has given problem. I try to insert something but it adds nothing and error 500, see the code: I know there are some security issues, I'll fix later.

<?php

use Phalcon\Di\FactoryDefault;
use Phalcon\Http\Response;
use Phalcon\Mvc\Micro;

error_reporting(E_ALL);

define('BASE_PATH', dirname(__DIR__));
define('APP_PATH', BASE_PATH . '/app');

try {

    /**
     * The FactoryDefault Dependency Injector automatically registers the services that
     * provide a full stack framework. These default services can be overidden with custom ones.
     */
    $di = new FactoryDefault();

    /**
     * Include Services
     */
    include APP_PATH . '/config/services.php';

    /**
     * Get config service for use in inline setup below
     */
    $config = $di->getConfig();

    /**
     * Include Autoloader
     */
    include APP_PATH . '/config/loader.php';

    /**
     * Starting the application
     * Assign service locator to the application
     */
    $app = new Micro($di);

    $app->post(
        "/api/membros",
        function () use ($app) {
            $phql  = "SELECT * FROM Membros";
            $dados = $app->modelsManager->executeQuery($phql);
            $data  = [];
            foreach ($dados as $dado) {
                $data[] = [
                    "id"         => $dado->id,
                    "id_usuario" => $dado->id_usuario,
                    "nome"       => $dado->nome,
                    "email"      => $dado->email,
                    "telefone"   => $dado->telefone,
                    "cpf"        => $dado->cpf,
                    "rg"         => $dado->rg,
                    "endereco"   => $dado->endereco,
                    "profissao"  => $dado->profissao,
                ];
            }
            echo json_encode($data);
        }
    );

    $app->get(
        "/api/membros/{id:[0-9]+}",
        function ($id) use ($app) {
            $phql  = "SELECT * FROM Membros WHERE Membros.id = " . $id;
            $dados = $app->modelsManager->executeQuery($phql);
            $data  = [];
            foreach ($dados as $dado) {
                $data[] = [
                    "id"         => $dado->id,
                    "id_usuario" => $dado->id_usuario,
                    "nome"       => $dado->nome,
                    "email"      => $dado->email,
                    "telefone"   => $dado->telefone,
                    "cpf"        => $dado->cpf,
                    "rg"         => $dado->rg,
                    "endereco"   => $dado->endereco,
                    "profissao"  => $dado->profissao,
                ];
            }
            echo json_encode($data);
        }
    );

    $app->post(
        "/api/membros",
        function () use ($app) {
            $insert = [
                'id_usuario' => $app->request->getPost('id_usuario'),
                'nome'       => $app->request->getPost('nome'),
                'email'      => $app->request->getPost('email'),
                'telefone'   => $app->request->getPost('telefone'),
                'cpf'        => $app->request->getPost('cpf'),
                'rg'         => $app->request->getPost('rg'),
                'endereco'   => $app->request->getPost('endereco'),
                'profissao'  => $app->request->getPost('profissao'),
            ];

            $phql = "INSERT INTO Membros (id_usuario, nome, email, telefone, cpf, rg,endereco, profissao) VALUES ('" . $insert['id_usuario'] . "','" . $insert['nome'] . "','" . $insert['email'] . "','" . $insert['telefone'] . "','" . $insert['cpf'] . "','" . $insert['rg'] . "','" . $insert['endereco'] . "','" . $insert['profissao'] . "')";

            echo $phql;
            $status = $app->modelsManager->executeQuery($phql);

            $response = new Response();
            if ($status->success() === true) {
                $response->setStatusCode(201, "Adicionado com Sucesso");
                $dados = Membros::findFirstBynome($insert['nome']);
                $response->setJsonContent(
                    [
                        'status' => "OK",
                        'data'   => $dados,
                    ]
                );
            } else {
                $response->setStatusCode(409, "Conflito");
                $erro = [];

                foreach ($status->getMessage() as $msg) {
                    $erros[] = $msg->getMessage();
                }

                $response->setJsonContent(
                    [
                        'status'   => "Erro",
                        'messages' => $erros,
                    ]
                );
            }
            return $response;
        }
    );

    $app->notFound(
        function () use ($app) {
            echo "Desculpe, não foi possivel atender sua solicatação";
        }
    );

    /**
     * Handle the request
     */
    $app->handle();

} catch (\Exception $e) {
    echo $e->getMessage() . '<br>';
    echo '<pre>' . $e->getTraceAsString() . '</pre>';
}

A couple of pointers:

In your post add

var_dump($app->request->getPost()) and then die() to ensure that data is indeed posted to your endpoint when you call it. Once you have confirmed that this is ok you can try using the model itself vs the model manager:

What is the namespace for Membros? Is it registered directly or does it live somewhere else? If you want to use it you will need to add the full namespace in the PHQL.

Another way to do this:

$record = new Membros();
$record->id_usuario = $app->request->getPost('id_usuario');
$record->nome       = $app->request->getPost('nome';
$record->email      = $app->request->getPost('email');
$record->telefone   = $app->request->getPost('telefone');
$record->cpf        = $app->request->getPost('cpf');
$record->rg         = $app->request->getPost('rg');
$record->endereco   = $app->request->getPost('endereco');
$record->profissao  = $app->request->getPost('profissao');

$result = $record->save();

if (false === $result) {
    // Record not saved
}

My best guess is that the model cannot be found because the namespace is not properly defined.

Now my head is more confused. Members is a model, could you show me exactly what the code looks like?

A model is just a file located somewhere in your project. So for instance:

/app/models/Membros.php

and the file should have something like this:

<?php

namespace MyApp\Models;

class Membros extends Phalcon\Mvc\Model
{
   // set source and other stuff here
}

In your autoloader you must tell Phalcon where Membros.php is. As you see in the above example I use MyApp as the namespace. Therefore your autoloader must tell Phalcon that MyApp\Models points to the /app/models/ folder.

PHQL (that you use) requires model names and those models must be able to be resolved using the autoloader.

Change your POST code with what I posted above. Have a look if your model can be correctly found and resolved and then we can pick it up from there.

Okay, my question is why does listing all data and searching for id work? No namespace error, just time to insert it from error 500 and save nothing

Then there is something coming from your database. Perhaps a field that cannot be null or some data inconsistency there. Check what data you send in and check the whole SQL statment that you intend on inserting.

The echo you have for $phql. Do the operation, take that echo result and run it against your database manually. You will have to of course replace the Membros with the actual name of your table. There should be something there indicating why data cannot be stored. `

I'd also add

ini_set('display_errors', 1);

error reporting wont work at all until you enable that!

E ai Rafaelmenon, eu percebi pelo teu código que tu é BR, então vou escrever aqui em PT-BR.

Ele está dando 500 pois a classe membros não foi instanciada.

$dados = Membros::findFirstBynome($insert['nome']);

Hi Rafaelmenom, i see you from Brazil, so i been write to you in Portuguese to better understanding. The error 500 it's because you don't start the class Membros inside the code.

After some conversations with @niden I made the changes and now it's like this, but it is entering the if error ie the result is giving false

    $app->post(
      "/api/membros",
      function() use ($app) {
        $record = new Membros();
        $record->id_usuario = $app->request->getPost('id_usuario');
        $record->nome       = $app->request->getPost('nome');
        $record->email      = $app->request->getPost('email');
        $record->telefone   = $app->request->getPost('telefone');
        $record->cpf        = $app->request->getPost('cpf');
        $record->rg         = $app->request->getPost('rg');
        $record->endereco   = $app->request->getPost('endereco');
        $record->profissao  = $app->request->getPost('profissao');

        $result = $record->save();

        if($result !== false) {
          echo 'acho q funcionou';
        } else {
          echo 'ainda não foi dessa vez';
        }
        return $result;
      }
    );

Try this:

<?php

$app->post(
    "/api/membros",
    function () use ($app) {

        /**
         * Add the record in the database
         */
        $record = new Membros();
        $record->id_usuario = $app->request->getPost('id_usuario', 'int');
        $record->nome       = $app->request->getPost('nome', 'string');
        $record->email      = $app->request->getPost('email', 'email');
        $record->telefone   = $app->request->getPost('telefone', 'string', '');
        $record->cpf        = $app->request->getPost('cpf', 'string', '');
        $record->rg         = $app->request->getPost('rg', 'string', '');
        $record->endereco   = $app->request->getPost('endereco', 'string', '');
        $record->profissao  = $app->request->getPost('profissao', 'string', '');

        /**
         * Save the record
         */
        $result = $record->save();

        /**
         * Check the Save
         */
        if (false === $result) {
            /**
             * Failure
             */
            $errors = [];
            foreach ($record->getMessages() as $message) {
                $errors[] = $message->getMessage();
            }

            $payload = [
                'status' => 'error',
                'data'   => $errors,
            ];
        } else {
            /**
             * Success
             */
            $payload = [
                'status' => 'success',
                'data'   => $record->toArray(),
            ];
        }

        $response = $app->response;

        $response->setHeader('Content-Type', 'application/json');
        $response->setContent(json_encode($payload));

        $response->send();
    }
);