So I'm a newbie at laravel framework and PyroCMS, I recently install PyroCMS and go to mydomain.com/register to try the registration function and I got the following error, but no idea how to solve it.
Error code:
}
/**
* Convert the given string to upper-case.
*
* #param string $value
* #return string
*/
public static function upper($value)
{
return mb_strtoupper($value, 'UTF-8');
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Highlighted line
}
/**
* Convert the given string to title case.
*
* #param string $value
* #return string
*/
public static function title($value)
{
return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8');
}
And
public static function substr($string, $start, $length = null)
{
return mb_substr($string, $start, $length, 'UTF-8');
}
Which the line return mb_strtoupper($value, 'UTF-8'); and return mb_substr($string, $start, $length, 'UTF-8'); is highlighted with an error log expects parameter 1 to be string, array given.
How can I solve it?
More info:
Error file: pyrocms/vendor/laravel/framework/src/Illuminate/Support/Str.php
Error screenshot:
You may or may not want to do something like this
public static function upper($value)
{
if(is_array($value)){
foreach($value as &$item){
$item = self::upper($item); //recursive
}
return $value;
}
return mb_strtoupper($value, 'UTF-8');
}
This will recursively call upper when it's an array and the effect will be that it will uppercase everything in $value. This may or may not be what you want.
Chances are you are passing the wrong data to this method.
To pass the right data you would do something like
$value['key'] = Class::upper($value['key']);
But I have no idea what value key should be, and I don't even know what class these methods reside in Class. I don't use laravel and I never heard of PyroCMS before.
If I used every framework that came along i would spend my days learning frameworks and not building them. I don't use laravel because I don't like the syntax blade uses, I am not a fan of query builders, probably these can be replaced but we already have everything build in a different framework. So there is no need to customize it to work the way I want it to when we already have a solution that works just fine.
That said, I do know PHP, I know it quite well in fact.
Related
A problem that we probably didn't know about when switching to PHP 8+:
Very often, in the rules we created earlier, we returned a message like this:
public function message(): array
{
return [$this->validator->errors()->messages()];
}
When using PHP 7.4 - this isn't a problem, but not for PHP 8+
Since looking "deeper" into how the laravel framework forms messages, we get an error in the replaceAttributePlaceholder method of the FormatsMessages class:
/**
* Replace the : attribute placeholder in the given message.
*
* #param string $message
* #param string $value
* #return string
*/
protected function replaceAttributePlaceholder($message, $value)
{
return str_replace(
[':attribute', ':ATTRIBUTE', ':Attribute'],
[$value, Str::upper($value), Str::ucfirst($value)],
$message
);
}
And indeed, if we open any editor and run the same code, but for two different versions, we'll get:
If you return the message like this:
public function message(): array
{
return $this->validator->errors()->messages();
}
We will avoid the error, but accordingly, the format of the message will be different - this doesn't suit me, and the format of the message should remain the same.
Does anyone have any ideas on how to save the format and fix the error?
Imagine a function like this
function mytrim($str,$where)
{
if ($where=="left") return ltrim($str)
if ($where=="right") return rtrim($str)
}
Its very important to me show what is the options of the where in this functions (right or left)
The best way I found to do it is
/**
* #param string $str
* #param left|right $where
* #return mixed|string
*/
will show "where: \left|\right"
There is a better way to do it ?
Leaving aside that I don't think you should have this function in the first place, you could make use of type hints and return types to document the arguments instead of using PHPDoc:
<?php declare(strict_types=1);
function mytrim(string $str, string $where): ?string
{
if ($where=="left") return ltrim($str);
if ($where=="right") return rtrim($str);
}
Docs tend to get outdated fast while function signatures are always current.
Now you could argue that this will not tell you what you can provide for $where and you'd still need the PHPDoc to know how to ltrim and rtrim. You could utilize constants for that though, e.g.
<?php declare(strict_types=1);
const MYTRIM_LEFT = 'left';
const MYTRIM_RIGHT = 'right';
function mytrim(string $str, string $where): ?string
{
if ($where === MYTRIM_LEFT) return ltrim($str);
if ($where === MYTRIM_RIGHT) return rtrim($str);
}
You'd still need to know that these constants exist though. That's why I'd probably convert your mytrim to a Strings class and define the constants declarations in there by. And/Or you add a check into the function that throws an error if the $where isn't "left" or "right".
As of PHP 8.1 you could use enums to make it even more clear:
<?php declare(strict_types=1);
enum MyTrim {
case Left;
case Right;
}
function mytrim(string $str, MyTrim $where): ?string
{
if ($where === MyTrim::Left) return ltrim($str);
if ($where === MyTrim::Right) return rtrim($str);
}
echo mytrim(" test", MyTrim::Left); // prints "test"
Everything there is to know about how to use the code is now directly visible in the signature.
But coming back to my initial remark: you should not have this function in the first place. Since you need to specify whether it's a left or right trim, you don't win anything over directly using ltrim and rtrim in your code.
I've learned most of my OOP practices from C#, and coded php primarily in MVC but without custom objects for data types (user information and such I primarily stored in associative arrays). I'm wanting to take what I've learned in C# (making structs, or data classes basically, to store specific types of data, such as a user record, or say an article's information) into php. This is so I can know exactly what data values to expect (because they're defined fields, instead of just added to an array), allowing a bit more abstraction between controller and view.
Is there a certain way to do this in php, and in the MVC design pattern specifically? I am curious where I should put the definitions of these new "data types."
Or am I just thinking about this in the wrong way, and there is a better way to do it?
EDIT:
A C# example of what I'm trying to accomplish:
class program1
{
public void main ()
{
Article randomArticle = getArticle (); //instead of returning an object array, it returns a defined data type with predefined fields, so I don't need to guess what's there and what isn't
Console.WriteLine(randomArticle.title);
Console.ReadLine();
}
public Article getArticle ()
{
return new Article("Sometitle", "SomeContent");
}
}
struct Article
{
public Title {get; private set;}
public Content {get; private set;}
public Article (string title, string content)
{
this.Title = title;
this.Content = content;
}
}
(idk if the above actually would compile, but it gives you the gist of what I'm attempting to do in PHP)
PHP is free of any logic you would like to implement. IMO, Ensuring data-types leads to a field of validations. I want you to check few terms, that will give you everything required.
Type Casting/ Juggling [docs here]
Casting is probably fastest way to stop unwanted input. The casts allowed are:
(int), (integer) - cast to integer
(bool), (boolean) - cast to boolean
(float), (double), (real) - cast to float
(string) - cast to string
(array) - cast to array
(object) - cast to object
(unset) - cast to NULL (PHP 5)
PHP Filters
PHP has a function filter_var (http://www.php.net/manual/en/function.filter-var.php) will helps you to compare a data type
var_dump(filter_var('bob#example.com', FILTER_VALIDATE_EMAIL));
var_dump(filter_var('http://example.com', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED));
PHP inbuild() functions
They are many functions in php, which can help you check the data types
is_array(): checks array
is_integer(): Check integer
is_object(): Check objects
is_float(): Checks Floating point number
ctype_digit(): Checks Integer
and many more
Regex Validation
You will be able to find many resources on this on the internet.
Other Resources
http://net.tutsplus.com/tutorials/php/sanitize-and-validate-data-with-php-filters/
http://www.phpro.org/tutorials/PHP-Type-Casting.html
Update
Your above method might turn into something like this
public function Article($title, $content) {
if(is_string($title)) { $this -> title = $title; }
if(is_string($content)) { $this -> content = $content; }
}
In PHP, you are free to write your own systems that accomplish MVC. Instead of rolling your own to start, though, I suggest looking into using an existing system. There's a huge ecosphere of us php types, and a long history. By some opinions, PHP is more well-established than a younger and faster evolving C#. It's also simpler, which is nice. Specifically, though: CakePHP is one I'd recommend. Drupal is more robust. And there's always Zend. Advantage of going Zend is the end-to-end solution from the editor to the server optimization and security.
p.s. c# is more mvvm
EDIT: code example
class Article {
protected $_title;
protected $_content;
public function setTitle( $title ) {
$this->_title = $title;
}
public function setContent( $content ) {
$this->_content = $content;
}
public function getTitle() {
return $this->_title;
}
public function getContent() {
return $this->_content;
}
/* magic not advisable; a technically valid technique, though it can lead to problems
public function __get( $property ) {
switch( $property ) {
case 'title': return $this->_title; break;
case 'content': return $this->_content; break;
default: break;
}
}
*/
}
my problem is the following: I am writing a login library.
This library has a function _validation() and this uses the validation library to validate the data.
With using normal validation methods it works just fine, but using a callback function just does not work. It is not called.
I call it like this.
$this->CI->form_validation->set_rules('user', 'Username', 'required|callback__check_user');
The functions name is _check_user and it uses the username _check_user($user).
The function itself works fine and I can also call it in the class ($this->_check_user('username')) with a working result.
I am guessing, there might be a problem because I am not workin in a controller so I have a CI instance $this->CI instead of just the original instance $this->
Does anyone have a clue how to fix this?
Thanks in advance.
Hey, I figured out a way that works for me. By just extending the Form_validation library in MY_Form_validation.php you can create custom validation methods. I think it is a clean way and it works perfectly fine. I build the below validation method to check for existing usernames and passwords. $value is something like table_name.fieldname.
I have not message set so that it will use the _exist messages from the lang files.
/**
* Exist
*
* checks if the entry exists in the database
* returns a boolean
*
* #access private
* #param string
* #param field
* #return boolean
*/
function _exist($str, $value)
{
list($table, $column) = explode('.', $value, 2);
$query = $this->CI->db->query("SELECT COUNT(*) AS count FROM $table WHERE $column = '$str'");
$row = $query->row();
return ($row->count > 0) ? TRUE : FALSE;
}
Thanks for your help though.
The form validation callback will only fire on a method inside the current controller.
Just do this in the controller you're using the callback:
function _check_user($user)
{
$this->load->model('login');
$result = $this->login->_check_user($user);
return $result;
}
I want to fetch a method's comments,take below method for example:
/**
* Returns the regex to extract all inputs from a file.
* #param string The class name to search for.
* #return string The regex.
*/
public function method($param)
{
//...
}
the result should be
Returns the regex to extract all inputs from a file.
#param string The class name to search for.
#return string The regex.
the way I find is use a function like file_get_content to get file content -> filter the method I want -> fetch the comment use regexp
it seems a bit complicated , is there any convenient way to archive this?
actually you can get a method's doc comments with getDocComment
$ref=new ReflectionMethod('className', 'methodName');
echo $ref->getDocComment();
If you want to use the comment in PHP for something check out getDocComment in php's reflection api
PHP Doc. Like Java Doc.
For a method dump I use this little function I composed.
It fetches all methods from provided class that are public(and thus of use to you).
I personally use a dump() method to nicely format the outputted array of method names and descriptions, but that's not needed if you wish to use it for something else :-)
function getDocumentation($inspectclass) {
/** Get a list of all methods */
$methods = get_class_methods($inspectclass);
/** Get the class name */
$class =get_class($inspectclass);
$arr = [];
foreach($methods as $method) {
$ref=new ReflectionMethod( $class, $method);
/** No use getting private methods */
if($ref->isPublic()) {
$arr[$method] = $ref->getDocComment();
}
}
/** dump is a formatting function I use, feel free to use your own */
return dump($arr);
}
echo getDocumentation($this);