generate number

Need Help! Please. :D




 public static function generateKode_Urut() {

        $_d = date("ymd");

        $_left = $_d;

        $_first = "0001";

        $_len = strlen($_left);

        $no = $_left . $_first;


        $last_po = DocumentServices::find(

                        array(

                            "select" => "id",

                            "condition" => "left(id, " . $_len . ") = :_left",

                            "params" => array(":_left" => $_left),

                            "order" => "id DESC"

        ));


        if ($last_po != null) {

            $_no = substr($last_po->id, $_len);

            $_no++;

            $_no = substr("0000", strlen($_no)) . $_no;

            $no = $_left . $_no;

        }


        return $no;

    }



i got this error




Getting unknown property: yii\db\ActiveQuery::id






line code error

 $_no = substr($last_po->id, $_len);



You are using find() method in wrong day.

You can use findOne() or findAll() passing conditions as parameters. You are not passing parameters as first parameters, pay attention.

http://www.yiiframework.com/doc-2.0/yii-db-baseactiverecord.html#findOne()-detail

http://www.yiiframework.com/doc-2.0/yii-db-baseactiverecord.html#findAll()-detail

thank you for your answer. sir

new error




Operator 'LEFT(ID, 6) = :_LEFT' requires two operands.






public static function generateKode_Urut() {

        $_d = date("ymd");

        $_left = $_d;

        $_first = "0001";

        $_len = strlen($_left);

        $no = $_left . $_first;


        $last_po = DocumentServices::find()->where(["left(id, " . $_len . ") = :_left", "params" => [":_left" => $_left]])->one();





        if ($last_po != null) {

            $_no = substr($last_po->id, $_len);

            $_no++;

            $_no = substr("0000", strlen($_no)) . $_no;

            $no = $_left . $_no;

        }


        return $no;

    }



Check the syntax of "where()".

yii\db\Query::where()

You are using an array in operator format for $condition parameter, but you should use a string or an array in hash format for it.

Using a string, the code will be:




$last_po = DocumentServices::find()

    ->where("left(id, " . $_len . ") = :_left", [":_left" => $_left])

    ->orderBy(["id" => SORT_DESC])

    ->one();



Here, the first parameter $condition is a string, and the 2nd parameter $params is an array of name-value pairs.

Or, you may use the hash format like this:




$last_po = DocumentServices::find()

    ->where(["left(id, " . $_len . ")" => $_left])

    ->orderBy(["id" => SORT_DESC])

    ->one();



Note that the hash format will automatically use the parameter binding, so you don’t have to use the second parameter $params.

[EDIT]

BTW, the way you generate the sequence number is dangerous. The method may return an identical number for different requests when your site has a heavy traffic.

thank you sir. :D

btw. before i have been used stored procedure to generate number, for to day i am trying to use this code.

thank you for your suggestion.

may be. do you have opinion, which one is the better? .

  1. use stored procedure (db side) or

  2. use this function (public static function generateKode_Urut())

The expected sequence of your design looks like this:

[list=1]

[*] Originally the number = 1.

[*] User A calls generateKode_Urut() to get the number + 1, that is 2.

[*] User A saves the number, that is 2

[*] User B calls generateKode_Urut() to get the number + 1, that is 3.

[*] User B saves the number, that is 3

[*] User C calls generateKode_Urut() to get the number + 1, that is 4.

[*] …

[/list]

But your site may receive multiple requests almost at the same time. In that case, something like the following can occur:

[list=1]

[*] Originally the number = 1.

[*] User A calls generateKode_Urut() to get the number + 1, that is 2.

[*] User B calls generateKode_Urut() to get the number + 1, that is 2.

[*] User A saves the number, that is 2

[*] User B saves the number, that is 2

[*] User C calls generateKode_Urut() to get the number + 1, that is 3.

[*] …

[/list]

Even if you are using a stored procedure, it won’t be a help to this problem.

For MySQL, LAST_INSERT_ID can be used to avoid this problem. Please check these:

http://ronaldbradford.com/blog/last_insert_idexpr-the-lesser-known-usage-2007-09-12/

http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

Thank you so much more, sir. excellent.