Jump to content

NotionCommotion

Members
  • Posts

    2,446
  • Joined

  • Last visited

  • Days Won

    10

Everything posted by NotionCommotion

  1. Is it generally considered good practice to explicitly pass $this arguments to sub-functions, or is it okay for the sub-function to directly get the value from $this? At least today, updateDB() will only use $this->id. class foo { private $id; public function __construct($id) { $this->id=$id; } public function updateValue($value) { // ... $this->updateDB($value,$this->id); // ... } private function updateDB($value,$id) { // Or should I just use $this->id? } }
  2. Well, you got me past the hard part. I could always just change $_SERVER to change the URI for testing. Thanks again.
  3. Perfect! Thank you! PHPed doesn't seem real good about documenting some features, or maybe I just can't find them. Do you know if there is something similar which will change the URI from say index.php to index.php/foo?
  4. Sarcasm? It is not ideal as it just allows me to test the methods.
  5. Thanks Requinx, Yea, I know my streaming thing was REALLY wrong, but was just grasping at straws. Your approach might work but that dang indention must have deleted half of it, and I will probably go with something like the following today. I still would like a better solution. <?php class request { public $method, $attr=[], $get=[], $post=[]; public function __construct($method,$request,$attr) { $this->method=$method; if($method=='GET'){$this->get=$request;} else {$this->post=$request;} $this->attr=$attr; } public function getMethod() { return $this->method; } public function getParsedBody() { return $this->post; } public function getQueryParams() { return $this->get; } public function getAttribute($name) { return $this->attr[$name]; } } class slim { public function __construct($config) { $db = $config['db_sql']; $this->db=new \PDO("mysql:host={$db['host']};dbname={$db['dbname']};charset={$db['charset']}",$db['username'],$db['password'],array(\PDO::ATTR_EMULATE_PREPARES=>false,\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY=>true,\PDO::ATTR_ERRMODE=>\PDO::ERRMODE_EXCEPTION,\PDO::ATTR_DEFAULT_FETCH_MODE=>\PDO::FETCH_ASSOC)); $account=new \myApp\Accounts($this->db); $this->account=$account->get('main_key'); $this->logger=null; } } ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); spl_autoload_register(function ($classname) { //Make better $parts = explode('\\', $classname); require "../classes/".end($parts).".php"; }); $config=parse_ini_file('../../config.ini',true); $config=[ 'db_sql'=>$config['mysql'], 'displayErrorDetails'=> true, 'determineRouteBeforeAppMiddleware' => true, ]; $slim=new slim($config); $request=new request('POST',['x'=>1],['y'=>2]); //Request Method, GET or POST array, atributes array $factory=new Factory($request,$slim); $rs=$factory->testSomething(/*...*/); echo('<pre>'.print_r($rs,1).'</pre>');
  6. For new projects, is it time to start using PHP 7? Why yes or no? Anything to watch out for? Thanks
  7. http://www.nusphere.com/products/phped.htm
  8. I second that. Once you start using, you will wonder why you didn't start earlier.
  9. Yea, that copy of a string thing didn't make any sense. How can Burp Suite allow one to debug the script line by line? Agree with using cURL for automated testing.
  10. How do I simulating a POST request? I do not wish to use cURL, but wish to execute the script directly in an IDE. It needs to be more than just setting the $_POST super variable, and needs to actually set the HTTP body header. Below is my unsuccessful attempt. Thank you PS. Why doesn't var_dump(file_get_contents('php://input')); display anything? <?php ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); function simulateRequest($method,$url,$get,$post) { $query=http_build_query($get); $_GET=$get; $_POST=$post; $_REQUEST=array_merge($_GET,$_POST,$_REQUEST); $_SERVER['REQUEST_METHOD']=$method; $_SERVER['REDIRECT_URL']=$url; $_SERVER['QUERY_STRING']=$query; $_SERVER['REQUEST_URI']=$url.($query?'?'.$query:null); if($query) {$_SERVER['REDIRECT_QUERY_STRING']=$query;} if(!empty($post)) { //HttpRequest::setBody (http_build_query($post)); //http://php.net/manual/it/httprequest.setbody.php $opts = ['http' =>['method' => 'POST','header' => 'Content-type: application/x-www-form-urlencoded','content' => http_build_query($post)]]; $context = stream_context_create($opts); $rawInput = fopen('php://input', 'r'); stream_copy_to_stream($context,$rawInput); } } simulateRequest('POST','/test/bla',[],['a'=>'A','b'=>'B','c'=>'C']); var_dump(file_get_contents('php://input')); print_r($_POST); use \Psr\Http\Message\ServerRequestInterface as Request; use \Psr\Http\Message\ResponseInterface as Response; require '../vendor/autoload.php'; $app = new \Slim\App(); $app->post('/test/{attr}', function (Request $request, Response $response) { echo('Attr:<pre>'.print_r($request->getAttribute('attr'),1).'</pre>'); exit('Params<pre>'.print_r($request->getParsedBody(),1).'</pre>'); }); $app->get('/test/{attr}', function (Request $request, Response $response) { echo('Attr:<pre>'.print_r($request->getAttribute('attr'),1).'</pre>'); exit('Params<pre>'.print_r($request->getQueryParams(),1).'</pre>'); }); $app->run();
  11. Since it works with one browser but not another, I expect it has nothing to do with the PHP code. Try adding echo('<pre>'.print_r($_POST,1).'</pre>'); at the top of your PHP. Are you getting the same data sent to the server? If not, maybe it has something to do with your browser configuration such as restricting cookies or JavaScript.
  12. I didn't realize that the slim object was passed to the container, and agree this approach is much better. Thanks! While I don't have a crush on static methods (I must admit, I once did and since learned my lesson), I still don't understand why you would want to have a bunch of error response classes with just a constructor.
  13. Daaahh... Must I say more? Thanks!!!
  14. Try this. What does it display? I would expect it is a row of data, and not the count that you expected. $result=odbc_exec($strcon, $sql); //executing select * statement //need help from here down $count=odbc_fetch_array($result); var_dump($count); Try the following. It should get one row at a time. while($row=odbc_fetch_array($result)) { var_dump($row); } If you want to know how many rows you get, experiment with http://php.net/manual/en/function.odbc-num-rows.php. odbc_fetch_array() and odbc_fetch_object() are basically the same but one returns an array and the other returns.. wait for it... an object. There is no reason to do one, and then the other, but if you truly wanted both, I am sure their is a function for it. PS. I believe a PDO version for obdc exists, and you should definitely us it and use prepared statements.
  15. I was getting an error, and changed $app->add(function(ServerRequestInterface $request, ResponseInterface $response, $next) use ($container) { to $app->add(function(Request $request, Response $response, $next) use ($container) {. I also got rid of the use ($container), however, doing both ways seemed to work find. Any issues with me doing so? All seems to work out until I have a invalid key, and am getting the below error. Do you know what I am doing wrong? $container['account'] = function () { return new \MyApp\Accounts(); }; $app->add(function(Request $request, Response $response, $next) { $key = $request->getHeaderLine('X-MyApp-Key'); if (empty($key)) { return \MyApp\ErrorResponse::missingKey(); } $account=$this->account; $account = $account->get($this->db,$key); if (!$account) { return \MyApp\ErrorResponse::invalidKey(); } $this->account=$account; return $next($request, $response); }); namespace MyApp; class ErrorResponse { public static function missingKey() { return ["status"=>"error","code"=>3,"message"=>"Missing key."]; } public static function invalidKey() { return ["status"=>"error","code"=>3,"message"=>"Invalid key."]; } } namespace MyApp; class Accounts { public function get($db,$key) { $stmt=$db->prepare('SELECT id,name FROM accounts WHERE main_key=?'); $stmt->execute([$key]); return $stmt->fetch(\PDO::FETCH_OBJ); } } Slim Application Error The application could not run because of the following error: Details Type: UnexpectedValueException Message: Middleware must return instance of \Psr\Http\Message\ResponseInterface File: /var/www/src/vendor/slim/slim/Slim/MiddlewareAwareTrait.php Line: 69 Trace #0 /var/www/src/vendor/slim/slim/Slim/MiddlewareAwareTrait.php(116): Slim\App->Slim\{closure}(Object(Slim\Http\Request), Object(Slim\Http\Response)) #1 /var/www/src/vendor/slim/slim/Slim/App.php(337): Slim\App->callMiddlewareStack(Object(Slim\Http\Request), Object(Slim\Http\Response)) #2 /var/www/src/vendor/slim/slim/Slim/App.php(298): Slim\App->process(Object(Slim\Http\Request), Object(Slim\Http\Response)) #3 /var/www/src/public/index.php(341): Slim\App->run() #4 {main}
  16. Thanks Ignace, Why have use ($container)? Isn't the container in $this? I like how you return the error response and just terminate performing the next route (better than my exit). Note related to Slim, but why do you use individual classes presumably just with a constructor for each error? Would it be better to have a single class and pass something to the constructor, or maybe use a static class?
  17. Thanks kicken, I guess I kind of knew that, but your excellent explanation made it sink in. Below is what I ended up doing. $container['factory'] = $container->protect(function ($request,$slim) { return new Factory($request,$slim); }); $app->get('/configure', function (Request $request, Response $response) { return $response->withJson(call_user_func($this->factory,$request,$this)->createConfig()->get()); }); If I decided not to use the Pimple protect method and instead pass a function, would it just be the following with the other part the same? $container['factory'] = $container->protect(function ($request,$slim) { return function($request,$slim) {new Factory($request,$slim);}; });
  18. Thanks Kicken, Will need to mull this over a bit. One initial question, however. Please explain \MyApp\Configure::class. $app->get('/configure', Controller(\MyApp\Configure::class));
  19. Thanks Kicken, I seem to be missing something with the Pimple approach. Also, how would it look to pass a function that returns the factory function? $app->get('/configure', function (Request $request, Response $response) { var_dump($this->random_func); echo("\n"); var_dump($this->random_func()); exit; }); object(Closure)#26 (0) { } Fatal error: Call to undefined method Slim\Container::random_func() in /var/www/src/public/index.php on line 166
  20. I think I am on the right track. Slim has a Pimple container feature where a function could be added such as $container['logger'] = function($config) {/* ... */}; and within the callback, it could be used as $this->logger->addInfo('Hi!');. I wish to create something similar, but instead it will create a factory object. My difficulty I believe is passing the variables to the $this->factory(). What am I doing wrong? One other thing I don't understand is how $config is getting to the logger function. I would have thought that $config is global, and as such, I would need to do $container['logger'] = function() use $config {/* ... */};. I appear to be incorrect as the logger script works as shown below, and would appreciate some clarification what is going on. Thanks $config=[/* settings */]; $app = new \Slim\App(["settings" => $config]); $container = $app->getContainer(); $container['logger'] = function($config) { $logger = new \Monolog\Logger('my_logger'); $file_handler = new \Monolog\Handler\StreamHandler("../logs/app.log"); $logger->pushHandler($file_handler); return $logger; }; $container['db'] = function($config) { /* settings */}; $container['account'] = function($config) { /* settings */}; $container['factory'] = function ($request,$slim) { return new \MyApp\factory($request,$slim); }; $app->get('/configure', function (Request $request, Response $response) { $this->logger->addInfo('Hello world!'); return $response->withJson($this->factory($request,$this)->get()); }); class factory { private $request,$slim; public function __construct($request,$slim) { $this->request=$request; $this->slim=$slim; } public function createConfig() { return new \MyApp\Configure(['logger'=>$this->logger,'db'=>$this->db,'account'=>$this->account]); } public function createDocument() { return new \MyApp\Document(['id'=>$this->request->getAttribute('id'),'logger'=>$this->logger,'db'=>$this->db,'account'=>$this->account]); } }
  21. I think I just need a factory!
  22. Configure is a class to set the configuration values. You are correct, it doesn't need any extra parameters, but I have other classes which do. Yes, passing the Slim application will work, but maybe gives too much.
  23. I have the following lines of code, and about 50 more similar ones which respond to different requests. Many of them just pass ['logger'=>$this->logger,'db'=>$this->db,'account'=>$this->account] to the class, but some pass a couple more parameters. $app->get('/configure', function (Request $request, Response $response) { $configure=new \MyApp\Configure(['logger'=>$this->logger,'db'=>$this->db,'account'=>$this->account]); return $response->withJson($configure->get()); }); I would like to type less regarding the the array passed to the class. While the following doesn't work, I hope it better conveys what I am trying to accomplish. Any suggestions? Thank you $get=function($extra=[]) { return array_merge($extra,['logger'=>$this->logger,'db'=>$this->db,'account'=>$this->account]); }; $app->get('/configure', function (Request $request, Response $response) { $configure=new \MyApp\Configure($get()); return $response->withJson($configure->get()); }); $app->get('/oneThatNeedsMore', function (Request $request, Response $response) { $configure=new \MyApp\Configure($get(['extra'=>123])); return $response->withJson($configure->foo()); });
  24. You know I love my fantasy code! I hope you know that I don't do it to make life easier for myself as it is far easier to slap down whatever I have previously written, and only do so in hopes that it better highlights what I am asking and makes it easier for others to either provide advice or for others to learn by the advice given. I've seen other posts with 500 lines of code, and it is difficult to know where to start, and it seems the objective is just to have someone write their code and not teach them to write for them self. Sounds like fishing! Just my two bits, for what it is worth... Okay, Template Method pattern is one option. Looks like we call the parent, and have the parent fill in the blanks using the child. I've been maybe wrongly dubious about calling the parent and having it call the child as it has eventually brought be down a dead end, but given my example, I see no issues. Are there other design patterns one might take? Why would one wish to take one pattern over another? I understand that this is a big question, and maybe there are documents already written on the subject, and if you know of any good ones, please direct me to them. If you feel like writing your own, I will surely welcome it as well! Thanks
  25. Given the following script, how should I eliminate duplicated script? class p { // ... } class c1 extends p { public function foo() { //Some common code to all foo's //Some specific code to c1::foo() which needs variables set above, and will set variables needed below. //Some common code to all foo's } } class c2 extends p { public function foo() { //Some common code to all foo's //Some specific code to c2::foo() which needs variables set above, and will set variables needed below. //Some common code to all foo's } } class c3 extends p { public function foo() { //Some common code to all foo's //Some specific code to c3::foo() which needs variables set above, and will set variables needed below. //Some common code to all foo's } }
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.