I'm wondering if it's possible to call a function from a name spaced file.
Currently the code below produces an error. I know it's possible to just pass the whole namespace, but is there a more automated way just using the alias of U?
use Helpers\User as U;
$t = call_user_func('U\something', 'test');
var_dump($t);
UPDATE
The way I solved this was by creating a function within that name spaced file that would return the file name spaced.
/**
*
* pntfn = Prepend namespace to function name
*
* #param $fn
*
* #return string
*/
function _pntfn($fn) {
return __NAMESPACE__.'\\'.$fn;
}
This then let's me do the following in a file
use Helpers\Users as U;
If I wanted to compose (functional programming) a function from my Users namespace file I would do the following;
$get_username_upper = F\compose('strtoupper', U\_pntfn( 'get_username' ));
Not my favorite implementation, but works for now. The con, is that you'd have to add this to all of your name spaced function files.
The trouble is U is resolved at compile time, so calling:
U\something
Literally becomes:
Helpers\User\something
This might still be invalid, since I know we also have the directive use function, so you may want to check that out as well.
Anyway, the string 'U\something' is a runtime constant, meaning U at this point doesn't actually refer to anything at all. So no, unfortunately this isn't possible.
Related
This may be very easy but I just can't find it.
When we use getLocale() we get value from config.app file, right?
In that file I have 'locale'=>'en'
Also there are other things like 'name', when I try to use app()->getName() or app()->name() it says it doesn't exist.
It works with config('app.name') same as config('app.locale'), I would like to know how does it work with locale but doesn't work for name?
Also I was searching for these methods getLocale but I can't find them that's main reason why am I asking this.
The function is declared at line 1039 in the Application class (Illuminate/Foundation/Application.php:1039) of Laravel 5.6.
That's why it's working for app()->getLocale() and not app()->getName().
/**
* Get the current application locale.
*
* #return string
*/
public function getLocale()
{
return $this['config']->get('app.locale');
}
So I started using this little library for creating a RESTful PHP server, right here.
In the code, I noticed that it appears that the comments are actually significant, in other words, if I change the comments, it actually changes the behavior of the code. Is this normal practice? I've never seen this used before and it seems weird to me to not ignore comments.
class TestController
{
/**
* Returns a JSON string object to the browser when hitting the root of the domain
*
* #url GET /
*/
public function test()
{
return "Hello World";
}
/**
* Logs in a user with the given username and password POSTed. Though true
* REST doesn't believe in sessions, it is often desirable for an AJAX server.
*
* #url POST /login
*/
public function login()
{
$username = $_POST['username'];
$password = $_POST['password']; //#todo remove since it is not needed anywhere
return array("success" => "Logged in " . $username);
}
/**
* Gets the user by id or current user
*
* #url GET /users/$id
* #url GET /users/current
*/
public function getUser($id = null)
{
// if ($id) {
// $user = User::load($id); // possible user loading method
// } else {
// $user = $_SESSION['user'];
// }
return array("id" => $id, "name" => null); // serializes object into JSON
}
Basically, the #url blocks actually define what request types to which URLs call the function below them. What is the scope of this, does it have to be the #lines right above the function? Is this standard PHP practice?
It is PHP Doc. See https://phpdoc.org/docs/latest/guides/docblocks.html and specifically https://phpdoc.org/docs/latest/guides/docblocks.html#tags
A tag always starts on a new line with an at-sign (#) followed by the name of the tag. Between the start of the line and the tag’s name (including at-sign) there may be one or more spaces or tabs.
Erm... Yes and No!
No, in the sense that it's not a normal PHP feature. In PHP, a comment is a comment and PHP makes no attempt to parse its content.
Yes in the sense that because PHP won't parse the comment, developers sometimes use it as a place to store data for their libraries. The Symfony framework is a good example.
In this case, the library you installed is parsing the comments in the class RestServer.php itself. You can read the class yourself, although there's some pretty hardcore PHP and Regex in there.
I am used to Yii's URL management:
site.com/controller/action/var1/value1/var2/value2
That way I can put my variables in any order in the URL or omit one and having a default value asigned:
public function actionFoo( $var1=22, $var2 ) { //Var1 is optional, Var2 must come.
}
Is there such thing in Symfony? I've searched but I found only hard-coded URL positions, like CodeIgniter, and that's something I find very annoying, because if I have a parameter in the middle of the URL I need to necessarily give it a value.
Example:
site.com/controller/action/false/false/value3
Maybe what I am used too is a bad practice, and I am open to learn other way.
Thanks
Symfony doesn't work that way.
If you need to map a value to a variable name then you need to use query strings: ?var1=value1&var2=value2.
Then, in your controller you can do $this->get('request')->query->get('var1', false) (false being the default value if var1 isn't set).
Otherwise you can define a default value in your route but it doesn't work the way you expect it to work.
You could extend the Routing component to mimic Yii's routing system but I wouldn't advise it because it would require some time.
All-in-all query strings will do exactly what you expect.
I have also found it to be a bit annoying as well, but with a little bit of work you can make the URLs work in Symfony by setting multiple routes to the same controller method. The catch is the order does matter.
This example use annotation but you could do the same thing with YAML, XML and PHP.
/**
* #Route("/whatever/{var2}/{var1}", name="whatever_allvars")
* #Route("/whatever/{var2}", name="whatever_onevar")
* #Template()
*/
public function actionFoo( $var1=22, $var2 ) {
//Var1 is optional, Var2 must come.
}
this would allow the following URLs:
site.com/whatever/var2/var1
site.com/whatever/var2
if you really want to make it match the sample URL give you could set it up like this.
/**
* #Route("/controller/action/var1/{var1}/var2/{var2}", name="whatever_allvars")
* #Route("/controller/action/var1/{var1}", name="whatever_onevar")
* #Template()
*/
public function actionFoo( $var1, $var2=22 ) {
//Var2 is optional, Var1 must come.
}
This would allow the following URLs:
site.com/controller/action/var1/value1/var2/value2
site.com/controller/action/var1/value1
Hopefully this gives you an idea what can be done in Symfony.
Using the Zend Framework and the url method for the view:
$this->url(array('field1' => this, 'field2' => 'is', 'field3' => 'my example'), 'route_name');
Where route_name is the name of the url route and each field# is retrieved from the database.
I noticed that by default it changes spaces in Controller/Action names into plus sign so that what looked like:
www.example.com/this is my example
to
www.example.com/this+is+my+example
I would like to change the separatoer from + to - to have something like
www.example.com/this-is-my-example
I know that another thread: How to change the separation character of Zend Url?
as documented a way to do it which I tried without success.
A thorough explanation on how to do it would be much appreciated.
EDIT2: I know where the problem lies if anyone is interested, it comes from the way the url is assemble, it uses urlencode which converts all non-alphanumeric characters expect - and _ and the spaces as +, there is no way to override that than replace the character create the url manually (as Maxime suggested) or create a custom url function replacing the characters (as suggest by aporat)...
Thanks!
If you really want to do that, you can extend the stock Zend_View_Helper_Url view helper and add your url logic into your view helper.
<?php
namespace Application\View\Helper;
class MyUrl extends \Zend_View_Helper_Url
{
/**
* Generates an url given the name of a route.
*
* #access public
*
* #param array $urlOptions Options passed to the assemble method of the Route object.
* #param mixed $name The name of a Route to use. If null it will use the current Route
* #param bool $reset Whether or not to reset the route defaults with those provided
* #return string Url for the link href attribute.
*/
public function myUrl(array $urlOptions = array(), $name = null, $reset = false, $encode = true)
{
return str_replace('+', '-', parent::url($urlOptions, $name, $reset, $encode));
}
}
and then just load your new view helper and you're good to go:
$helper = new \Application\View\Helper\MyUrl;
$this->view->registerHelper($helper, 'myUrl');
Unfortunately, you can't set anything before calling the url(...) function to achieve what you want to do. The reason is that when the URL is assembled, it uses the php urlencode(...) function.
That said, you still have many options:
1) You simply don't use the url(...) function and create your URLs manually. (Best option)
2) You create a new helper that acts like url(...) but add extra changes to the function to achieve what you want to do.
3) You take the output of the url(...) function and do a str_replace to change + with -. (I DO NOT recommend that option)
Personally, I create all my URLs manually to avoid this kind of problem.
I'm implementing a function called attach. I'm looking for a way to take a param that is either a file path or a file's contents. Here's what I have:
/**
* #param name - name of the file
* #param file - either a file or a file path
*/
function attach($name, $file) {
$attachment = array();
$attachment['name'] = $name;
if(map($file)) {
$attachment['filepath'] = $file;
$attachment['file'] = file_get_contents($file);
} else {
$attachment['file'] = $file;
$attachment['filepath'] = getcwd();
}
}
/**
* #param filepath - can take multiple forms
* ie. ui:form:text.css => ui/form/text.css
* text.css => getcwd().'text.css'
* /ui/form/text.css => /ui/form/text.css
*
* #return if file exists - return file path
* if not found - return false
*/
function map($filepath) {
// ... too long to post
}
The map function allows you to turn namespaces (using ":") into filepaths.
The issue I'm worried about is if an error is made in the filepath (ie. someone types in the file path wrong) I don't want it to think that since the file doesn't exist, it must be file contents
Also: if possible, i'd rather not edit map() as it would require me to change a bunch of code - consider map as a black box.
Finally: I put this example together quickly - so please do not discuss the shortcomings of getcwd(), and other syntactical issues. I have a more elaborate system in place in map()
Thanks!
Matt Mueller
Even if PHP had better support for method overloading, you'd have a hard time here since both vars (filepath and file contents) would probably be a string. What is preventing you from just creating a couple of wrapper methods, like attach_filepath(..), attach_filecontents(..)? Or, if you are set on having one method, you could add a third param, like:
function attach($name, $file, $filecontents=false) {
I agree that it would probably be a bad idea to try to guess the users' intentions based on the contents of a var that would have the same type in both cases.
Before adding the attachment your code could use a function like file_exists to determine if what seems like a path actually is a path and the file does in fact exist. Additionally you may want to check if the path refers to a folder or a file.