Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Restfull API, with Form
  • Hi, i'm starting learning FuelPhp.
    I got a little website (On movies reservation)

    I would like to made an API Rest with FuelPhp.

    I created my controller called "api.php"
    Got one table names : Movies
    - ID
    - Name
    - Type
    - Date
    - DateLocation
    - EndDate

    I have create a function called get_MoviesName()
    She work well when i enter in url : http://localhost:8888/api/movies/?id=1

    I have create an other function called get_MovieByType()
    She work well when i enter in url : http://localhost:8888/api/moviesByType/?type=adventure
    I got all my Adventure Movies

    Now i wanted to make a concatenation/fusion between this two functions.
    For example http://localhost:8888/api/movies/?id=&type=adventure

    How can i do that ... ?

    I call my function with an Ajax Call on an other page called "test.php"

    Thank for your help :)
  • Parameters are passed as method arguments, with a URL like http://localhost:8888/api/movies/?id=&type=adventure you define the method like so:

    public function get_movies($id, $type = null)
    {
       // your code
    }

    This makes the id required, and the type optional, so both your URL constructs work.
  • To the point, I couldn't use function pararmeters in my REST controller... I don't want to say, that something not works, may be I do something wrong rather :)

    I just want ot say, there is one another ability to works with get parameters by Input::get() or Input::param() - it works good :)
  • HarroHarro
    Accepted Answer
    Sorry, my bad, wasn't paying enough attention to what you wrote.

    Fuel hasn't been designed to use GET variables, it uses URI segments. Additional segments are mapped to action method arguments.

    If you want to use GET variables, you have to use Input::get(). I try not to use Input::param(), it is not so much a problem with GET requests, but it allows you to easily fake a POST using the URI's query string, and that might be dangerous.
  • But maybe if we use DB::query(Our request)->execute() ?
  • I don't see the relation between GET variables and a DB query?
  • I have change all my project and it's work now.

    But new question : 

    I want to use this url : /api/movies/?id_type=2

    Search my movies with in parameter id_type.

    I have do a function :

    public function get_movies($id_type = null)
    {
    $movies = \DB::query("SELECT DISTINCT id_movies, name FROM movie WHERE id_type='$id_type'") -> execute();

    ...
    ...
    ...
    }

    But with this function i can only access to 
    api/movies/2
    and not api/movies/?id_type=2

    How can i do this ? Because in my test page i had a form GET where we can enter the id_type and he return in url : api/movies/?id_type=
  • HarroHarro
    Accepted Answer
    That is what I wrote.

    If you want to use GET variables, you need to get them using Input::get(). Fuel is designed to use URI segments.

    And I have to warn you: writing queries like that is VERY insecure, your site will be open to SQL injection, and hacked within seconds. Use the query builder, and ALWAYS validate your input!
  • And what is my new queries with your method ? 
    Because i can't use DISTINCT with or no ?

    public function get_movies($id_type = null)
    if (Input::get('movies')
    {
    $movies = \Model_Movies::find(????)
  • HarroHarro
    Accepted Answer
    If your table has an ORM model, you would use

    // assuming 0 is an invalid default value
    $movies = \Model_Movies::find_by_id_type( \Input::get('movies', 0));

    If you don't use ORM:

    // you don't need as_object() if you want array's returned
    $movies = DB::select()->from('movies')->where('id_type', '=', \Input::get('movies', 0))->execute()->as_object();

    Note again that neither of these examples use validated input, you should really do that. So if your id_type should be a  number, make sure it is!
  • HUm... 

    Class 'Api\DB' not found
  • HarroHarro
    Accepted Answer
    If you're in a namespaced class, you need to prefix classes from other namespaces.

    So you need to use \DB (Fuel's core classes live in the global namespace).

    Perhaps brush up on some basic PHP skills first?
  • Yeah just a missing :) 

    Work now :) 

    And if i use a form for my parameter URL, and i want this form return url like : /api/movies/{id_type}
    ?

  • HarroHarro
    Accepted Answer
    In terms of validation there is no difference, it is not more complex to execute a SQL injection attack via a URI segment.
  • Thank you Harro Verton ! 


    EDIT : Last answers. 

    How can i add optional parameter ? (i have already read the doc).

    Exemple : url type : /api/movies/{id_type} and an optional /date
  • Define it in the argument list with a default:

    public function get_movies($id, $date = null)
    {
        // do we have a date?
        if ($date)
        {
           // do something
        }

        // do we have a second argument
        if (func_num_args() == 2)
        {
           // do something
        }
    }

    if null is acceptable input (or any default is), you can use the second example to check if the date was passed as well...
  • Okay thank, but now i got three tables : 

    Table book :
    - id
    - title
    - id_author

    Table author
    - id
    - name
    - id_type

    Table type
    - id 
    - nameOfType

    I would like to get my books with in parameter "id_author" and optional parameter "id_type".
    For example if i filter all books of a type.

    I try : 

    public function get_books($id_author, $id_type = null)
        {
            if ($id_author == 0 && $id_type){
                $books= \DB::query("SELECT DISTINCT id, title FROM book LEFT JOIN book ON author.id LEFT JOIN author ON type.id")->execute();
    ....
    ....
    } elseif ($id_author) {
    $books= \DB::query("SELECT distinct id, title FROM book WHERE id_author=" .$id_author." ORDRE BY id") -> execute();
    ...

    ...
    }


    But didn't work ....
  • When working with related tables, it's a lot easier to use the ORM:

    $query = Model_Book::query()
        ->related('author')
        ->related('author.type');

    if ($id_author)
    {
        $query->where('id_author', '=', $id_author);
    }

    if ($id_type)
    {
        $query->where('author.id_type', '=', $id_type);
    }

    $results = $query->get();

    This is assuming you have setup your Model_Book, Model_Author and Model_Type correctly, including the has_many relations between them.
  • This is an example of my Model_Book

    class Model_Book extends \Orm\Model
    {
    protected static $_table_name = 'book';

    protected static $_properties = array (
    'id',
    'title',
    'id_author',
    };
    }

    Actually Model_Book, Model_Author and Model_Type follow this file.

    I really want use DB::query ... 
  • You make it complicated for yourself, and you sacrifice security, your DB queries are not secure, you don't manually construct SQL anymore these days.

    But if you insist, nobody is stopping you. Al least use the DB query builder then, instead of constructing the SQL by hand, so that input is properly escaped.

  • I know but if we can make things complicated we can make the simple ;) 

    So, what is the correct request with JOIN ? I tried to many time...


    I want that :

    URL : 
    api/book/10

    -> Return all book of the author who got the 10 id
    THIS actually work.

    And second time :
    URL:
    api/book/ if no id exist -> then use the second parameter (OPTIONAL parameter)
    -> Return all book of a type. (by using the id of type).
  • Something like:

    $results = DB::select()
        ->from('books')
        ->join('authors')->on('authors.id', '=', 'books.author_id')
        ->where('authors.type_id', '=', $type_id)
        ->execute();
  • Yeah work well thank you ! 

    but i'm adding : 
    -> order_by('id') and not working ... you know why ? 
  • HarroHarro
    Accepted Answer
    Have you enabled all error reporting? Have you enabled the profiler, and DB profiling? And what does that tell you?

    My guess: 'id' is ambiguous, you have two 'id' columns in the result, and I assume the author id overwrites the book id... Use the table name prefix to indicate on which column you want to order.

    This should give you a DB error though, so if you don't get that reported, your error reporting in develop mode isn't fully enabled.
  • I contacted you by private message :)
  • Hi,

    I got table named Library 
    In this table I have all my books i have at home.

    So table is like : 
    - id
    - title
    - id_author
    - author
    - id_type
    - type

    I would like to get my book(s) with optional parameters :  id , id_author and id_type

    When i try with the id, it's good.

    But when i try for id_author ... not working :/

    $library = \DB::query("SELECT id, title, author, type FROM library WHERE id_author = " . $id_author . " ORDER BY id") ->execute();

    Fuel\Core\Database_Exception [ 42000 ]:
    SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ORDER BY id' at line 1 with query: "SELECT DISTINCT id, title, author, type FROM library WHERE id_author= ORDER BY id"


    EDIT : I would like to do this with ORM :) 

    I tried :
    if (Input::get('id_author'){
     $library = \Model_library::find('last', array('id','title','author','type', array('where' => array(array('id_author, Input::get('id_author'))))));


    EDIT2: It's good now :) 

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion