├── README.md ├── cfscript.md ├── cfscript_pt_br.md └── licence.md /README.md: -------------------------------------------------------------------------------- 1 | The cfscript.md file is the one you want to be looking at. -------------------------------------------------------------------------------- /cfscript.md: -------------------------------------------------------------------------------- 1 | 2 | Table of Contents 3 | ================= 4 | 5 | * [CFScript documentation](#cfscript-documentation) 6 | * [Comments](#comments) 7 | * [Statements](#statements) 8 | * [Variables](#variables) 9 | * [Operators](#operators) 10 | * [Decision](#decision) 11 | * [Arithemetic](#arithemetic) 12 | * [Increment/decrement](#incrementdecrement) 13 | * [Inline assignment](#inline-assignment) 14 | * [Boolean](#boolean) 15 | * [Decision](#decision-1) 16 | * [Ternary operator](#ternary-operator) 17 | * [Null-coalescing variation](#null-coalescing-variation) 18 | * [Conditions](#conditions) 19 | * [if/elseif/else](#ifelseifelse) 20 | * [switch](#switch) 21 | * [try/catch/finally, throw/rethrow](#trycatchfinally-throwrethrow) 22 | * [Iteration](#iteration) 23 | * [General-purpose for loop](#general-purpose-for-loop) 24 | * [Pre-condition loop](#pre-condition-loop) 25 | * [Post-condition loop](#post-condition-loop) 26 | * [Array loop](#array-loop) 27 | * [For statement](#for-statement) 28 | * [arrayEach()](#arrayeach) 29 | * [Array.each()](#arrayeach-1) 30 | * [Struct loop](#struct-loop) 31 | * [For statement](#for-statement-1) 32 | * [structEach()](#structeach) 33 | * [Struct.each()](#structeach-1) 34 | * [Query loop](#query-loop) 35 | * [List loop](#list-loop) 36 | * [File loop](#file-loop) 37 | * [Date/time range loop](#datetime-range-loop) 38 | * [Other flow control statements](#other-flow-control-statements) 39 | * [Abort processing](#abort-processing) 40 | * [Exit from current file](#exit-from-current-file) 41 | * [Code reuse](#code-reuse) 42 | * [Include](#include) 43 | * [Module](#module) 44 | * [Components / interfaces](#components--interfaces) 45 | * [Attributes](#attributes) 46 | * [Interface](#interface) 47 | * [Properties](#properties) 48 | * [Functions](#functions) 49 | * [Arguments](#arguments) 50 | * [Function/argument annotations](#functionargument-annotations) 51 | * [Function expressions](#function-expressions) 52 | * [Calling functions dynamically](#calling-functions-dynamically) 53 | * [Import](#import) 54 | * [Object creation](#object-creation) 55 | * [File system operations](#file-system-operations) 56 | * [Directories](#directories) 57 | * [Files](#files) 58 | * [Database](#database) 59 | * [Query](#query) 60 | * [Stored Procedure](#stored-procedure) 61 | * [Insert](#insert) 62 | * [Update](#update) 63 | * [DB Info](#db-info) 64 | * [Transactions](#transactions) 65 | * [Debugging](#debugging) 66 | * [Dump](#dump) 67 | * [Log](#log) 68 | * [Trace](#trace) 69 | * [Timer](#timer) 70 | * [General / Miscellaneous](#general--miscellaneous) 71 | * [Output](#output) 72 | * [File Encoding](#file-encoding) 73 | * [Save content](#save-content) 74 | * [Threading](#threading) 75 | * [Locking](#locking) 76 | * [Image / XLS manipulation](#image--xls-manipulation) 77 | * [PDF Manipulation](#pdf-manipulation) 78 | * [Elements of tag-based CFML with no specific CFScript implementation](#elements-of-tag-based-cfml-with-no-specific-cfscript-implementation) 79 | * [CFC-based solutions](#cfc-based-solutions) 80 | * [http.cfc](#httpcfc) 81 | * [mail.cfc](#mailcfc) 82 | * [The rest](#the-rest) 83 | 84 | # CFScript documentation 85 | 86 | This attempts to document all of CFScript, as a resource for people migrating from old-school tag-based code to script-based code. The reason I am doing this is because neither ColdFusion nor Railo/Lucee provide much (or in the case of Railo/Lucee: _any_) useful [documentation of CFScript](https://wikidocs.adobe.com/wiki/display/coldfusionen/The+CFScript+language). 87 | 88 | This is not a document for converting tags to script. It is not written from a point of view of "if you use ```` then you need to instead use [some script construct]". It simply documents CFScript. 89 | 90 | There are some syntax-neutral solutions to some CFML constructs which are listed at the bottom of the document. These are the CFCs found in [customtag]/com/adobe/coldfusion. These are not CFScript constructs per se, but related enough to be relevant here. 91 | 92 | It is also not an exercise in teaching CFML (or at least the script part). It assumes you know what you're doing, and is purely a reference. 93 | 94 | I assume Railo 4.2/Lucee 4.5 or ColdFusion 11, except where stated. 95 | 96 | 97 | ### Comments 98 | ```cfc 99 | // single line comment 100 | ``` 101 | ```cfc 102 | a=1; // single line comment at end of line 103 | ``` 104 | ```cfc 105 | /* 106 | multiple 107 | line 108 | comment 109 | */ 110 | ``` 111 | ```cfc 112 | /* 113 | multiple line 114 | /* comments */ 115 | cannot be nested 116 | */ 117 | ``` 118 | 119 | In this case, the commented bit is `/* multiple line /* comments */`, making the next bit a syntax error. 120 | 121 | ### Statements 122 | 123 | Statements end in semi-colons: 124 | ```cfc 125 | a = 1; 126 | ``` 127 | Semi-colons are _generally_ optional on Railo/Lucee: 128 | ```cfc 129 | a = 1 130 | ``` 131 | 132 | Where "generally" means "if the end of the statement is unambiguous without a semi-colon". It is better to just always use semi-colons. 133 | 134 | Block statements (with curly braces) do not have semi-colons: 135 | ```cfc 136 | while (condition) { 137 | // statements 138 | } 139 | ``` 140 | 141 | ### Variables 142 | 143 | Assigning a variable: 144 | ```cfc 145 | varName = "foo"; 146 | ``` 147 | 148 | Assigning a function-local variable: 149 | ```cfc 150 | var varName = "foo"; // analogous to local.varName = "foo"; 151 | ``` 152 | 153 | Note that the var keyword can appear inline in most statements where a variable is first initialised, eg: 154 | ```cfc 155 | for (var i=1; i <= 10; i++); 156 | ``` 157 | 158 | Assigning a dynamically-named variable: 159 | ```cfc 160 | varName = "foo"; 161 | "#varName#" = "bar"; 162 | writeOutput(foo); // bar 163 | ``` 164 | ![trycf-logo] Run this example on trycf.com 165 | 166 | This is the same as with a `` tag, but confuses some people due to it being slightly odd-looking. Obviously one can also use associative array syntax too (eg: `variables[varName] = "bar";`. This is preferable as it's more clear what's going on). 167 | 168 | Defaulting a variable: 169 | ```cfc 170 | param numeric variableName=defaultValue; // where "numeric" could be any type 171 | ``` 172 | For more complex situations: 173 | ```cfc 174 | param name="variableName" type="regex" pattern="."; // any cfparam attribute is supported 175 | ``` 176 | 177 | ### Operators 178 | 179 | All operators available to tag-based code still work in CFScript. In addition, CFScript has these ones: 180 | 181 | #### Decision 182 | ```cfc 183 | a == 1; // equality 184 | a < 1; // less than 185 | a <= 1; // less-than-or-equal 186 | a >= 1; // greater-than-or-equal 187 | a > 1; // greater than 188 | a != 1; // inequality 189 | a <> 1; // inequality (Railo/Lucee only) 190 | ``` 191 | ![trycf-logo] Run this example on trycf.com 192 | #### Arithemetic 193 | 194 | ##### Increment/decrement 195 | ```cfc 196 | // increment 197 | a = 1; 198 | b = a++; // b=1, a=2 // postfix operators returns value, then peforms action (in this case: increments a) 199 | c = ++a; // c=3, a=3 // prefix operator peforms action then returns result 200 | ``` 201 | ```cfc 202 | // decrement 203 | a--; // a=2 204 | --a; // a=1 205 | ``` 206 | ![trycf-logo] Run this example on trycf.com 207 | ##### Inline assignment 208 | ```cfc 209 | a += 2; // equivalent to a=a+2 210 | a -= 3; // equivalent to a=a-3 211 | a *= 4; // equivalent to a=a*4 212 | a /= 5; // equivalent to a=a/5 213 | a %= 6; // equivalent to a=a%6 214 | s &= "a"; // equivalent to s = s & "a" 215 | ``` 216 | ![trycf-logo] Run this example on trycf.com 217 | #### Boolean 218 | ```cfc 219 | !a; // NOT a 220 | a && b; // a AND b 221 | a || b; // a OR b 222 | ``` 223 | ![trycf-logo] Run this example on trycf.com 224 | #### Decision 225 | 226 | ##### Ternary operator 227 | ```cfc 228 | result = condition ? trueExpression : falseExpression; 229 | 230 | //eg: 231 | coinTossResult = randRange(0,1) ? "heads" : "tails"; 232 | ``` 233 | ![trycf-logo] Run this example on trycf.com 234 | ```cfc 235 | // NB: only one of trueExpression or falseExpression is evaluated: 236 | a = 1; 237 | b = 1; 238 | c = false ? ++a : ++b; // a=1, b=2, c=2 239 | ``` 240 | ![trycf-logo] Run this example on trycf.com 241 | ##### Null-coalescing variation 242 | ```cfc 243 | result = left ?: right; // left-hand expression is used unless it is null, in which case the right one is used 244 | 245 | //eg: 246 | a = d ?: "default"; // a = default 247 | ``` 248 | ![trycf-logo] Run this example on trycf.com 249 | ```cfc 250 | d = 1; 251 | a = d ?: "default"; // a = 1 252 | ``` 253 | ![trycf-logo] Run this example on trycf.com 254 | 255 | Note that whilst this appears to be the same as other language's "Elvis" operator, it is not the same. The "Elvis" operator checks for `false` (and in some languages `null` is falsey); this operator checks specifically for `null`. This is likely due to a misunderstanding one the part of Adobe (and perpetuated by the Lucee devs when copying it). 256 | 257 | ### Conditions 258 | 259 | #### if/elseif/else 260 | ```cfc 261 | if (booleanExpression) 262 | // single statement executed if booleanExpression is true 263 | else if (anotherBooleanExpression) 264 | // single statement executed if anotherBooleanExpression is true 265 | else 266 | // single statement executed if condition(s) are false 267 | ``` 268 | ```cfc 269 | if (booleanExpression) { 270 | // multiple statements executed if booleanExpression is true 271 | } else if (anotherBooleanExpression) { 272 | // multiple statements executed if anotherBooleanExpression is true 273 | } else { 274 | // multiple statements executed if condition(s) are false 275 | } 276 | ``` 277 | ![trycf-logo] Run this example on trycf.com 278 | #### switch 279 | ```cfc 280 | switch (expression) { 281 | case "some constant value": // value can be dynamic on Railo/Lucee 282 | // statements executed if expression = "some constant value" 283 | break; // exit switch statement 284 | case "a different constant value": 285 | // statements executed if expression = "a different constant value" 286 | // if there is no break, then processing continues to execute statements until a break is encountered... 287 | // ... but subsequent case evaluations are not made. A switch is basically a GOTO mechanism, which does a... 288 | // single GOTO the first matching case. It is NOT a series of if/elseif/else statements 289 | case "third constant value": 290 | // statements executed if expression = "a different constant value" or "third constant value" 291 | break; 292 | case "4th value": 293 | case "5th value": 294 | // statements executed if expression is one of "4th value" or "5th value" 295 | break; 296 | default: 297 | // statements executed if no case was fulfilled (or if the last fulfilled case did not have a break) 298 | break; 299 | } 300 | ``` 301 | ![trycf-logo] Run this example on trycf.com 302 | #### try/catch/finally, throw/rethrow 303 | ```cfc 304 | try { 305 | // statements 306 | 307 | throw "message"; // throws an Application exception, with the given message 308 | 309 | // or 310 | throw (type="ExceptionType", message="message", detail="detail", errorCode="errorCode", extendedInfo="extendedInfo"); // despite appearances, this is NOT a function 311 | 312 | // or 313 | throw (object=JavaExceptionObject); 314 | } 315 | catch (SomeExceptionType variableContainingExceptionObject) { 316 | // statements executed if code in try block errors with a SomeExceptionType exception 317 | 318 | rethrow; // rethrows the caught exception 319 | } 320 | catch (SomeOtherExceptionType variableCOntainingExceptionObject) { 321 | // statements executed if code in try block errors with a SomeOtherExceptionType exception 322 | } 323 | catch (any variableCOntainingExceptionObject) { 324 | // statements executed if code in try block errors with any not-yet-caught exception type 325 | } 326 | finally { 327 | // statements executed in any case, INCLUDING unhandled exceptions. This code ALWAYS runs 328 | } 329 | ``` 330 | 331 | ### Iteration 332 | 333 | #### General-purpose for loop 334 | ```cfc 335 | for (initialisation; condition; repetition) statement; 336 | ``` 337 | 338 | or: 339 | ```cfc 340 | for (initialisation; condition; repetition) { 341 | // statements 342 | } 343 | ``` 344 | 345 | EG: 346 | ```cfc 347 | for (i=1; i <=5; i++) writeOutput(i); // just the following single statement is looped over 348 | ``` 349 | 350 | or: 351 | ```cfc 352 | for (i=1; i <=5; i++) { 353 | // all statements within the block are looped over 354 | result = i * 2; 355 | writeOutput(result); 356 | } 357 | ``` 358 | 359 | The general perception is that this is the only form of a general-purpose for() loop: initialising a counter variable, testing it and adjusting it (increment, decrement). This is not the case. Each of the statements can be _anything_ (the condition needs to evaluate to a boolean), and indeed are optional. This is an endless loop, equivalent to while (true): 360 | ```cfc 361 | for (;;) 362 | ``` 363 | 364 | A very contrived example to demonstrate the freedom one has with the parameters of the for(): 365 | ```cfc 366 | i=0; 367 | for (; true; writeOutput(i)) { 368 | if (++i > 5) break; 369 | } 370 | ``` 371 | 372 | In general, all looping constructs have either the single-statement or block-of-statements syntax. I'll only offer the more common (and recommended, for code-clarity) block syntax henceforth. 373 | 374 | #### Pre-condition loop 375 | 376 | This form of loop evaluates a single condition at the beginning of each iteration, and continues to loop whilst the condition is true: 377 | ```cfc 378 | while (condition) { 379 | // statements 380 | } 381 | ``` 382 | 383 | This form of loop will execute zero or more times. 384 | 385 | #### Post-condition loop 386 | 387 | This form of loop evaluates a single condition at the beginning of each iteration, and continues to loop whilst the condition is true: 388 | ```cfc 389 | do { 390 | // statements 391 | } while (condition); 392 | ``` 393 | 394 | This form of loop will execute _one_ or more times. It's important to consider that the body of the loop will always run the first time, because no condition is evaluated until the _end_ of the loop. 395 | 396 | #### Array loop 397 | 398 | ##### For statement 399 | ```cfc 400 | for (element in [1,2,3,4,5]) { 401 | writeOutput(element); // 12345 402 | } 403 | ``` 404 | 405 | ##### arrayEach() 406 | ```cfc 407 | arrayEach(["a","b","c"], function(element,index,array) { 408 | writeOutput("#index#:#element#;"); // 1:a;2:b;3:c; 409 | }); 410 | ``` 411 | 412 | ##### Array.each() 413 | ```cfc 414 | a = ["a","b","c"]; 415 | a.each(function(element,index,array) { 416 | writeOutput("#index#:#element#;"); // 1:a;2:b;3:c; 417 | }); 418 | ``` 419 | 420 | Note that Railo/Lucee can call methods directly on a literal, so this works: 421 | ```cfc 422 | ["a","b","c"].each(function(element,index,array) { 423 | writeOutput("#index#:#element#;"); // 1:a;2:b;3:c; 424 | }); 425 | ``` 426 | 427 | #### Struct loop 428 | 429 | ##### For statement 430 | ```cfc 431 | struct = {a=1,b=2,c=3}; 432 | for (key in struct) { 433 | writeOutput("#key#:#struct[key]#;"); // a:1;b:2;c:3; (order of keys not guaranteed, obviously) 434 | } 435 | ``` 436 | 437 | ##### structEach() 438 | ```cfc 439 | structEach(struct, function(key,value,struct) { 440 | writeOutput("#key#:#value#;"); // a:1;b:2;c:3; 441 | }); 442 | ``` 443 | 444 | ##### Struct.each() 445 | ```cfc 446 | struct.each(function(key,value,struct) { 447 | writeOutput("#key#:#value#;"); // a:1;b:2;c:3; 448 | }); 449 | ``` 450 | 451 | #### Query loop 452 | ```cfc 453 | q = queryNew("id,data", "integer,varchar",[ 454 | [11, "aa"], 455 | [22, "bb"], 456 | [33, "cc"] 457 | ]); 458 | for (row in q){ 459 | writeOutput("#q.currentRow#:#row.id#:#row.data#;"); // 1:11:aa;2:22:bb;3:33:cc; 460 | } 461 | ``` 462 | 463 | Using grouping: 464 | ```cfc 465 | q = queryNew("pk,fk,data", "integer,integer,varchar",[ 466 | [1, 10, "aa"], 467 | [2, 20, "bb"], 468 | [3, 20, "cc"], 469 | [4, 30, "dd"], 470 | [5, 30, "ee"], 471 | [6, 30, "ff"] 472 | ]); 473 | cfloop(query=q, group="fk") { 474 | writeOutput("#fk#"); 475 | cfloop() { 476 | writeOutput("#pk#:#data#
"); 477 | } 478 | writeOutput("
"); 479 | } 480 | ``` 481 | 482 | Railo/Lucee only: 483 | ```cfc 484 | loop query=q group="fk" { 485 | writeOutput("#fk#"); 486 | loop { 487 | writeOutput("#pk#:#data#
"); 488 | } 489 | writeOutput("
"); 490 | } 491 | ``` 492 | 493 | #### List loop 494 | ```cfc 495 | list = "a;b;c"; 496 | listEach(list, function(element,index,list) { 497 | writeOutput("#index#:#element#;"); // 1:a;2:b;3:c; 498 | }, ";"); 499 | 500 | // or 501 | 502 | list.each(function(element,index,list) { 503 | writeOutput("#index#:#element#;"); // 1:a;2:b;3:c; 504 | }, ";"); 505 | 506 | // or (ColdFusion only, see [RAILO-3207](https://issues.jboss.org/browse/RAILO-3207)) 507 | 508 | for (element in "a,b,c,d,e") { 509 | writeOutput(element); // abcde 510 | } 511 | ``` 512 | 513 | I am not sure how one would specify a delimiter for the last example: it does not seem supported. 514 | 515 | Railo/Lucee only: 516 | ```cfc 517 | cfloop(list="a;b;c", index="element", delimiters=";") { 518 | writeOutput(element); // abc 519 | } 520 | 521 | // or 522 | loop list="a;b;c" index="element" delimiters=";" { 523 | writeOutput(element); // abc 524 | } 525 | ``` 526 | 527 | #### File loop 528 | ```cfc 529 | filePath = getCurrentTemplatePath(); 530 | cfloop(file=filePath, index="chars", characters=16, charset="UTF-8"){ 531 | writeOutput(chars); // outputs the contents of this file 532 | } 533 | ``` 534 | 535 | Railo/Lucee only: 536 | ```cfc 537 | loop file=filePath index="chars" characters=16 charset="UTF-8" { 538 | writeOutput(chars); 539 | } 540 | ``` 541 | 542 | #### Date/time range loop 543 | 544 | ColdFusion has no specific CFScript-specific construct for this as of ColdFusion 11 545 | 546 | Work around: 547 | ```cfc 548 | from = now(); 549 | to = dateAdd("d", 7, from); 550 | 551 | for (date=from; dateCompare(date, to, "d") <= 0; date = dateAdd("d", 1, date)) { 552 | writeOutput(dateTimeFormat(date, "yyyy-mm-dd HH:nn:sstt") & "
"); 553 | } 554 | ``` 555 | 556 | Railo/Lucee only: 557 | ```cfc 558 | cfloop(from=from, to=to, index="date", step=createTimespan(1,0,0,0)) { 559 | writeOutput(dateTimeFormat(date, "yyyy-mm-dd HH:nn:sstt") & "
"); 560 | } 561 | 562 | // or 563 | 564 | loop from=from to=to index="date" step=createTimespan(1,0,0,0) { 565 | writeOutput(dateTimeFormat(date, "yyyy-mm-dd HH:nn:sstt") & "
"); 566 | } 567 | ``` 568 | 569 | #### Iteration flow control 570 | 571 | cfcontinue: 572 | ```cfc 573 | for (i=1; i <= 5; i++) { 574 | writeOutput("#i# is "); 575 | if (i mod 2) { 576 | writeOutput("ODD
"); 577 | continue; 578 | } 579 | writeOutput("EVEN
"); 580 | } 581 | ``` 582 | 583 | ### Other flow control statements 584 | 585 | #### Request Redirect 586 | 587 | ```cfc 588 | /* cflocation */ 589 | // ColdFusion 590 | location(url="http://example.com", statuscode="301 OR 302", addtoken=false); 591 | 592 | // Railo/Lucee 593 | location url="http://example.com", statuscode="301 OR 302", addtoken=false; 594 | ``` 595 | 596 | #### Abort processing 597 | ```cfc 598 | abort; 599 | 600 | // or 601 | 602 | abort "error message"; 603 | ``` 604 | 605 | #### Exit from current file 606 | 607 | ```cfc 608 | exit; 609 | 610 | //or 611 | 612 | exit "method"; 613 | ``` 614 | 615 | ### Code reuse 616 | 617 | #### Include 618 | 619 | ```cfc 620 | include "pathToFile"; 621 | 622 | // or 623 | 624 | include "pathToFile" runonce=true; 625 | ``` 626 | 627 | #### Module 628 | 629 | ```cfc 630 | // Railo/Lucee 631 | module template="inc.cfm" attr1="val1" attr2="val2"; 632 | 633 | // ColdFusion 634 | cfmodule(template="inc.cfm", attr1="val1", attr2="val2"); 635 | ``` 636 | 637 | ### Components / interfaces 638 | 639 | ```cfc 640 | component { 641 | 642 | } 643 | ``` 644 | 645 | #### Attributes 646 | ```cfc 647 | component extends="Parent" { 648 | 649 | } 650 | ``` 651 | 652 | Or: 653 | 654 | ```cfc 655 | /** 656 | * @extends Parent 657 | */ 658 | component { 659 | 660 | } 661 | ``` 662 | 663 | Note that the comment for annotations is `/**` not simply `/*`. 664 | 665 | Also note that the latter syntax does not currently work on Railo (see [RAILO-3169](https://issues.jboss.org/browse/RAILO-3169)). 666 | 667 | #### Interface 668 | 669 | ```cfc 670 | interface { 671 | public void function f(required numeric x); // note no braces, and ends with semi-colon 672 | } 673 | ``` 674 | 675 | #### Properties 676 | 677 | Basic: 678 | 679 | ```cfc 680 | property string myProperty; 681 | ``` 682 | 683 | With additional parameters: 684 | 685 | ```cfc 686 | property type="string" name="myProperty" default="default value"; // and all the same attributes as `` 687 | ``` 688 | 689 | #### Functions 690 | 691 | Basic: 692 | 693 | ```cfc 694 | function f() { // assumes public function, returntype any 695 | 696 | } 697 | ``` 698 | 699 | With access and return type modifiers: 700 | 701 | ```cfc 702 | private void function f() { 703 | // statements 704 | } 705 | ``` 706 | 707 | #### Arguments 708 | 709 | Basic: 710 | ```cfc 711 | function f(x) { // optional argument of type "any" 712 | //statements 713 | } 714 | ``` 715 | 716 | Type: 717 | ```cfc 718 | function f(numeric x) { // optional argument of type "numeric" 719 | //statements 720 | } 721 | ``` 722 | Required: 723 | ```cfc 724 | function f(required numeric x) { // required argument of type "numeric" 725 | // statements 726 | } 727 | ``` 728 | Default value: 729 | ```cfc 730 | function f(numeric x = 0) { // optional argument of type "numeric" with default value of 0 731 | // statements 732 | } 733 | ``` 734 | 735 | #### Function/argument annotations 736 | ```cfc 737 | /** 738 | * @x.hint hint for argument x 739 | * @x.type numeric 740 | * @x.required true 741 | */ 742 | function f(x) { 743 | // statements 744 | } 745 | ``` 746 | 747 | Note these annotations do not current correctly work on Railo (see [RAILO-3170](https://issues.jboss.org/browse/RAILO-3170)) 748 | 749 | Also note that this does not currently work on ColdFusion (see [3808960](https://bugbase.adobe.com/index.cfm?event=bug&id=3808960)) 750 | ```cfc 751 | /** 752 | * @x.type numeric 753 | * @x.default 0 // this causes a compile error 754 | */ 755 | function f(x) { 756 | // statements 757 | } 758 | ``` 759 | 760 | #### Function expressions 761 | ```cfc 762 | f = function(x) { 763 | // statements 764 | }; 765 | ``` 766 | 767 | Functions defined by function expressions use closure, functions defined by a function statement do not 768 | 769 | Annotations for function expressions are not supported on ColdFusion ([3808978](https://bugbase.adobe.com/index.cfm?event=bug&id=3808978)); are supported on Railo, but have same shortcomings as noted above. 770 | 771 | #### Calling functions dynamically 772 | ```cfc 773 | test = new Test(); 774 | methodToCall = "f"; 775 | argumentsToPass = {x=1}; 776 | result = invoke(test, methodToCall, argumentsToPass); 777 | ``` 778 | 779 | Railo/Lucee-only: 780 | ```cfc 781 | result = test[methodToCall](argumentCollection=argumentsToPass); 782 | ``` 783 | 784 | #### Import 785 | ```cfc 786 | import com.domain.app.package.*; 787 | ``` 788 | 789 | #### Object creation 790 | ```cfc 791 | myObj = createObject(type, "path.to.class"); // along with other type/situation-specific arguments 792 | 793 | // or 794 | 795 | myObj = new path.to.some.cfc.file(); // NB: will call the CFC's init() (by default), or method identified by the initmethod attribute of the component (bug in Railo: [RAILO-2294](https://issues.jboss.org/browse/RAILO-2294)) 796 | ``` 797 | 798 | ### File system operations 799 | 800 | #### Directories 801 | ```cfc 802 | // simple directory creation 803 | directoryCreate("path/to/directory"); 804 | ``` 805 | ```cfc 806 | // using other optional attributes 807 | cfdirectory(action="create", directory="path/to/directory", mode="777"); 808 | ``` 809 | ```cfc 810 | // Railo/Lucee only 811 | directory action="create" directory="path/to/directory" mode="777"; 812 | ``` 813 | ```cfc 814 | // delete 815 | directoryDelete("path/to/directory"); 816 | ``` 817 | ```cfc 818 | // list 819 | listing = directoryList("path/to/directory", true, "query", "*.cfm", "size desc"); // CF11 added an additional "type" attribute. Not currently supported on Railo/Lucee 820 | ``` 821 | ```cfc 822 | // rename 823 | directoryRename("path/to/directory", "path/to/new/directory"); 824 | ``` 825 | 826 | #### Files 827 | ```cfc 828 | // read 829 | // text 830 | if (fileExists("path/to/file")) { 831 | result = fileRead("path/to/file"); 832 | } 833 | 834 | // or 835 | fileHandle = fileOpen("path/to/file", "read"); 836 | result = fileRead(fileHandle, bytesToRead); 837 | fileClose(fileHandle); 838 | 839 | // or 840 | fileHandle = fileOpen("path/to/file", "read"); 841 | while (!fileIsEOF(fileHandle)) { 842 | result = fileReadLine(fileHandle); 843 | } 844 | fileClose(fileHandle); 845 | 846 | ``` 847 | ```cfc 848 | // binary 849 | result = fileReadBinary("path/to/file"); 850 | 851 | //or 852 | fileHandle = fileOpen("path/to/file", "readbinary"); 853 | result = fileRead(fileHandle, bytesToRead); 854 | ``` 855 | ```cfc 856 | // append 857 | fileHandle = fileOpen("path/to/file", "append"); 858 | fileWrite(fileHandle, textToAppend); 859 | fileClose(fileHandle); 860 | ``` 861 | ```cfc 862 | // copy 863 | fileCopy("path/to/file", "path/to/copyOfFile"); 864 | ``` 865 | ```cfc 866 | // delete 867 | fileDelete("path/to/file"); 868 | ``` 869 | ```cfc 870 | // move / rename 871 | fileMove("path/to/file", "new/path/to/file"); 872 | ``` 873 | ```cfc 874 | // upload 875 | fileUpload("path/to/upload/file/to"); 876 | fileUpload(destination [, fileField [, accept [, nameConflict]]]); 877 | 878 | fileUploadAll("path/to/upload/files/to"); 879 | fileUploadAll(destination [, fileField [, accept [, nameConflict]]]); 880 | ``` 881 | ```cfc 882 | // write 883 | fileWrite("path/to/file", data); 884 | 885 | // or 886 | 887 | fileWrite(fileHandle, data); 888 | ``` 889 | 890 | ### Database 891 | 892 | #### Query 893 | ```cfc 894 | // general form 895 | recordset = queryExecute(sqlString, params, options); 896 | ``` 897 | ```cfc 898 | // with params array 899 | numbers = queryExecute(" 900 | SELECT columns 901 | FROM table 902 | WHERE id BETWEEN ? AND ? 903 | ", 904 | [1,4], 905 | { 906 | datasource ="myDsn", 907 | result = "result" // this is analogous to the result attribute of `` 908 | }); 909 | ``` 910 | ```cfc 911 | // with params struct 912 | numbers = queryExecute(" 913 | SELECT columns 914 | FROM table 915 | WHERE id BETWEEN :low AND :high 916 | ",{low=2,high=3}); 917 | ``` 918 | 919 | To qualify parameters with SQL types you can specify the equivalent of the cfqueryparam options with the parameters in the following way: 920 | 921 | ```cfc 922 | // with sql types in params struct 923 | numbers = queryExecute(" 924 | SELECT columns 925 | FROM table 926 | WHERE id BETWEEN :low AND :high 927 | ", 928 | { 929 | low = { value = 2, 930 | cfsqltype = "cf_sql_integer" 931 | }, 932 | high = { value = 3, 933 | cfsqltype = "cf_sql_integer" 934 | } 935 | }); 936 | ``` 937 | 938 | For versions prior to ColdFusion 11 (in which queryExecute() was implemented), there is a CFC-based solution: [Query.cfc](https://wikidocs.adobe.com/wiki/display/coldfusionen/query). An example is as follows: 939 | ```cfc 940 | numbers = new Query( 941 | sql = " 942 | SELECT columns 943 | FROM table 944 | WHERE id BETWEEN :low AND :high 945 | ", 946 | parameters =[ 947 | {name="low", value=2}, 948 | {name="high", value=3} 949 | ] 950 | ).execute().getResult(); 951 | ``` 952 | 953 | #### Stored Procedure 954 | ```cfc 955 | cfstoredproc(procedure="procName") { 956 | cfprocparam(type="in", cfsqltype="cf_sql_varchar", value="someValue"); 957 | cfprocresult(name="result",resultSet=1); 958 | cfprocresult(name="result2",resultSet=2); 959 | } 960 | ``` 961 | 962 | Railo/Lucee only 963 | ```cfc 964 | storedproc procedure="procName" 965 | dataSource = "myDataSource" 966 | result="response" 967 | returncode="true" { 968 | procparam type="in" cfsqltype="cf_sql_varchar" value="someValue"; 969 | procparam type="out" cfsqltype="cf_sql_integer" variable="myVariable"; 970 | procresult resultSet=1 name="result"; 971 | procresult resultSet=2 name="result2"; 972 | } 973 | ``` 974 | 975 | There is a change request you should vote for, to implement this syntax: 976 | ```cfc 977 | options = { 978 | datasource = "scratch_mssql", 979 | fetchclientinfo = true, 980 | returncode = true 981 | }; 982 | params = [ 983 | {value=URL.low, type="INTEGER"}, 984 | {value=URL.high, type="INTEGER"}, 985 | {type="out", variable="inclusiveCount", type="INTEGER"}, 986 | {type="out", variable="exclusiveCount", type="INTEGER"} 987 | ]; 988 | 989 | result = executeProcedure("uspGetColours", params, options); 990 | ``` 991 | 992 | See ColdFusion ticket: [3791737](https://bugbase.adobe.com/index.cfm?event=bug&id=3791737); Railo ticket: [RAILO-3184](https://issues.jboss.org/browse/RAILO-3184), and earlier blog article: '[ColdFusion 11: calling a stored procedure from script. And can we please stop wearing out our "c" and "f" keys?](http://blog.adamcameron.me/2014/03/coldfusion-11-calling-stored-procedure.html#executeProcedure)'. 993 | 994 | #### Insert 995 | 996 | Railo/Lucee only: 997 | ```cfc 998 | insert datasource="myDataSource" tableName="myTable" formFields="list,of,form,fields"; // arguments the same as ``. datasource is optional 999 | ``` 1000 | 1001 | Note: there is a bug with this: [RAILO-3180](https://issues.jboss.org/browse/RAILO-3180). 1002 | 1003 | ColdFusion only: 1004 | ```cfc 1005 | cfinsert(datasource="myDataSource", tableName="myTable", formFields="list,of,form,fields"); // arguments the same as `` 1006 | ``` 1007 | 1008 | Note that datasource is currently required, which is a bug: [3814079](https://bugbase.adobe.com/index.cfm?event=bug&id=3814079). 1009 | 1010 | #### Update 1011 | 1012 | Railo/Lucee only: 1013 | ```cfc 1014 | update datasource="myDataSource" table="myTable" formFields="list,of,form,fields"; // arguments the same as ``. datasource is optional 1015 | ``` 1016 | 1017 | Note the same bug applies here as does with insert. 1018 | 1019 | ColdFusion only: 1020 | ```cfc 1021 | cfupdate(datasource="myDataSource", table="myTable", formFields="list,of,form,fields"); // arguments the same as `` 1022 | ``` 1023 | 1024 | #### DB Info 1025 | ```cfc 1026 | cfdbinfo(type="tables", name="info"); // arguments the same as `` 1027 | ``` 1028 | 1029 | Railo/Lucee only: 1030 | ```cfc 1031 | dbinfo type="tables" name="info"; // arguments the same as `` 1032 | ``` 1033 | 1034 | #### Transactions 1035 | ```cfc 1036 | transaction { 1037 | try { 1038 | // stuff to do 1039 | transaction action="commit"; 1040 | } 1041 | catch (any e) { 1042 | transaction action="rollback"; 1043 | } 1044 | } 1045 | ``` 1046 | 1047 | Note that all attributes of `` are supported as space-separated name/value pairs. 1048 | 1049 | ### Debugging 1050 | 1051 | #### Dump 1052 | ```cfc 1053 | writeDump(myVar); // can use either ordered or named arguments. 1054 | ``` 1055 | With named arguments: 1056 | ```cfc 1057 | writeDump(var=myVar, output=ExpandPath('/debug/log.txt')); 1058 | ``` 1059 | 1060 | Railo/Lucee only: 1061 | ```cfc 1062 | dump(myVar) 1063 | ``` 1064 | 1065 | #### Log 1066 | ```cfc 1067 | writeLog("text to log"); // can use either ordered or named arguments. 1068 | ``` 1069 | 1070 | #### Trace 1071 | ```cfc 1072 | // Railo/Lucee only 1073 | trace category="test" text="trace text" { // plus all same params as `` 1074 | // stuff to trace 1075 | } 1076 | ``` 1077 | ```cfc 1078 | // COLDFUSION only 1079 | trace(category="test", text="trace text") { // plus all same params as `` 1080 | // stuff to trace 1081 | } 1082 | // note that CF11 incorrectly records timing information (see [3811003](https://bugbase.adobe.com/index.cfm?event=bug&id=3811003)) 1083 | ``` 1084 | 1085 | #### Timer 1086 | ```cfc 1087 | cftimer(label="timer label" type="outline") { // plus all same params as `` 1088 | // stuff to time 1089 | } 1090 | ``` 1091 | ```cfc 1092 | // Railo/Lucee only 1093 | timer label="timer label" type="outline" { // plus all same params as `` 1094 | // stuff to time 1095 | } 1096 | ``` 1097 | 1098 | ### General / Miscellaneous 1099 | 1100 | #### Output 1101 | ```cfc 1102 | writeOutput(expression); // expression must resolve to a string 1103 | ``` 1104 | 1105 | Railo/Lucee only: 1106 | ```cfc 1107 | echo(expression); // expression must resolve to a string 1108 | ``` 1109 | 1110 | #### File Encoding 1111 | ```cfc 1112 | pageencoding "UTF-8"; 1113 | ``` 1114 | 1115 | Note that this only works in CFC files on ColdFusion ([3712167](https://bugbase.adobe.com/index.cfm?event=bug&id=3712167)). It works correctly on Railo/Lucee. 1116 | 1117 | #### Save content 1118 | ```cfc 1119 | savecontent variable="saved" { 1120 | writeOutput("stuff to save"); 1121 | } 1122 | ``` 1123 | 1124 | #### Threading 1125 | ```cfc 1126 | thread action="run" name="threadName" { 1127 | // code to run in separate thread here 1128 | } 1129 | thread action="join" name="threadName,anotherThreadName"; 1130 | ``` 1131 | 1132 | #### Locking 1133 | ```cfc 1134 | lock name="lockName" timeout=1 throwontimeout=true { 1135 | // code to lock 1136 | } 1137 | ``` 1138 | 1139 | #### Image / XLS manipulation 1140 | 1141 | The function equivalents of [``](https://wikidocs.adobe.com/wiki/display/coldfusionen/Image+functions) and [``](https://wikidocs.adobe.com/wiki/display/coldfusionen/Spreadsheet+functions) are all well documented, and are not specifically CFScript constructs. 1142 | 1143 | #### PDF Manipulation 1144 | 1145 | I have to concede I have never ever done any work with PDFs, so cannot make an informed comment on the CFScript equivalents. However in lieu of particular CFScript-specific constructs that I am aware of, the generic syntax ought to work, eg: 1146 | 1147 | ColdFusion: 1148 | ```cfc 1149 | cfdocument(format="PDF") { 1150 | // mark-up here 1151 | } 1152 | ``` 1153 | Railo/Lucee: 1154 | ```cfc 1155 | document format="PDF" { 1156 | // mark-up here 1157 | } 1158 | ``` 1159 | 1160 | The same should work on other PDF-oriented tags. For versions of ColdFusion prior to CF11, there is a PDF.cfc (similar to Query.cfc, and also in cfusion/CustomTags/com/adobe/coldfusion). I have never used it, do not know how it works, and have no interest in finding out. If someone would like to donate some example code, I will integrate it here. 1161 | 1162 | 1163 | ### Elements of tag-based CFML with no _specific_ CFScript implementation 1164 | 1165 | #### CFC-based solutions 1166 | 1167 | As far as I can tell, there is no CFScript-specific implementations for the following pieces of functionality: 1168 | 1169 | * `` 1170 | * `` 1171 | * `` 1172 | * `` 1173 | * `` 1174 | * `` 1175 | * `` 1176 | * `` 1177 | 1178 | There are CFC wrappers for these in cfusion/CustomTags/com/adobe/coldfusion. These are not CFScript-specific solutions per se - one can just as easily use them in tag-based code - but can be included here for the sake of completeness. I personally do not use these constructs, and as they are not part of CFScript, did not attempt to include them here. Feel free to document and include them if you so choose. 1179 | 1180 | #### http.cfc 1181 | 1182 | ColdFusion (CF9+): 1183 | 1184 | __The pattern seems to be `set{ATTRIBUTENAME}( value );` for setting attributes that are normally set via the `` tag__ 1185 | 1186 | ```cfc 1187 | // there's a built-in CFC that handles this in CF9+ 1188 | httpService = new http(); 1189 | httpService.setMethod( "post" ) 1190 | httpService.setCharset( "utf-8" ); 1191 | 1192 | // the API provider may require you to export this cert 1193 | // so you’ll need to save it in a secure place… 1194 | // and reference it here 1195 | httpService.setClientCert( "#ExpandPath(‘.’)#/my_cert.p12" ); 1196 | httpService.setClientCertPassword( "mypassword!" ); 1197 | httpService.setUrl( "https://api.sample.com/" ); 1198 | 1199 | // these params are form fields to POST 1200 | httpService.addParam(type="formfield", name="field1", value="1111"); 1201 | httpService.addParam(type="formfield", name="field2", value="some text here"); 1202 | 1203 | // this is the cfscript way to grab the response 1204 | httpResponse = httpService.send().getPrefix(); 1205 | 1206 | writeDump(httpResponse); 1207 | ``` 1208 | 1209 | #### mail.cfc 1210 | 1211 | ColdFusion (CF9+): 1212 | 1213 | __The pattern seems to be `set{ATTRIBUTENAME}( value );` for setting attributes that are normally set via the `` tag__ 1214 | 1215 | ```cfc 1216 | mailerService = new mail(); 1217 | /* set mail attributes using implicit setters provided */ 1218 | mailerService.setType("html"); 1219 | mailerService.setCharset( "utf-8" ); 1220 | mailerService.setTo( "adam@sample.com" ); 1221 | mailerService.setFrom( "test@sample.com;joe@sample.com" ); 1222 | mailerService.setSubject( "Super interesting subject" ); 1223 | 1224 | /* add mailparams */ 1225 | mailerService.addParam( file=expandpath(form.attachment), type="text/plain", remove=false ); 1226 | // create the body 1227 | savecontent variable="mailBody"{ 1228 | WriteDump( CGI ); 1229 | WriteDump( SESSION ); 1230 | } 1231 | // send the email 1232 | mailerService.send( body=mailBody ); 1233 | ``` 1234 | 1235 | 1236 | #### The rest 1237 | 1238 | To use any other functionality not listed here within CFScript, one needs to use the generalised syntax. 1239 | 1240 | On Railo/Lucee this is a matter of removing the "``", and using normal block syntax (curly braces) where the tag-version is a block-oriented tag. 1241 | 1242 | On ColdFusion (CF11+), replace the "``" with "`)`", and comma-separate the attributes. Note that this will make the construct _look_ like a function, but it actually is not, and cannot be used like a function, eg this is invalid syntax: 1243 | 1244 | ```cfc 1245 | result = cfhttp(method="post", url="http://example.com"); 1246 | ``` 1247 | 1248 | Some tags take a block of code / text within them. Blocks are represented with curly braces, similar to a flow-contrl statement. 1249 | 1250 | ```cfc 1251 | cfmail(attributeCollection = attributesforCfmail) { 1252 | cfmailpart(type="text/plain") { 1253 | writeOutput("If you are seeing this, your e-mail client does not support HTML messages."); 1254 | } 1255 | cfmailpart(type="text/html") { 1256 | writeOutput(htmlVersionOfMessage); 1257 | } 1258 | } 1259 | 1260 | ``` 1261 | 1262 | Note how text needs to be "output" using `writeOutput`. Note also how sub-tags (`cfmailpart` here) are also expressed using the same rules as parent tags. 1263 | 1264 | * * * 1265 | 1266 | [![Creative Commons License](https://i.creativecommons.org/l/by/4.0/88x31.png)](http://creativecommons.org/licenses/by/4.0/) 1267 | This work is licensed under a [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/). 1268 | 1269 | [trycf-logo]: http://trycf.com/img/trycf-logo-tiny.png "TryCF.com" 1270 | -------------------------------------------------------------------------------- /cfscript_pt_br.md: -------------------------------------------------------------------------------- 1 | 2 | Indice 3 | 4 | 5 | ================= 6 | 7 | * [CFScript documentação](#Documentação-CFScript) 8 | * [Comentários](#Comentários) 9 | * [Afirmações](#Afirmações) 10 | * [Variáveis](#Variáveis) 11 | * [Operadores](#Operadores) 12 | * [Decisão](#Decisão) 13 | * [Aritmética](#Aritmética) 14 | * [Incremento / decremento](#Incremento-decremento) 15 | * [Atribuição inline](#Atribuição-inline) 16 | * [Boleano](#boolean) 17 | * [Decisão](#Decisão-) 18 | * [Operador Ternário](#Operador-ternário) 19 | * [Variação de coalescência nula](#Variação-de-coalescência-nula) 20 | * [Condições](#Condições) 21 | * [if/elseif/else](#ifelseifelse) 22 | * [switch](#switch) 23 | * [try/catch/finally, throw/rethrow](#trycatchfinally-throwrethrow) 24 | * [Iteração](#Iteração) 25 | * [Uso geral para loop](#Uso-geral-para-loop) 26 | * [Pré-condição loop](#Pré-condição-loop) 27 | * [Pós-condição loop](#Pós-condição-loop) 28 | * [Array loop](#array-loop) 29 | * [Para declaração](#for-statement) 30 | * [arrayEach()](#arrayeach) 31 | * [Array.each()](#arrayeach-1) 32 | * [Estrutura loop](#struct-loop) 33 | * [Para declaração](#for-statement-1) 34 | * [structEach()](#structeach) 35 | * [Struct.each()](#structeach-1) 36 | * [Query loop](#query-loop) 37 | * [Lista loop](#list-loop) 38 | * [Arquivo loop](#file-loop) 39 | * [Date/time range loop](#datetime-range-loop) 40 | * [Outras declarações de controle de fluxo](#other-flow-control-statements) 41 | * [Abortar processamento](#abort-processing) 42 | * [Sair do arquivo atual](#exit-from-current-file) 43 | * [Reutilização de codigo](#code-reuse) 44 | * [Incluir ](#include) 45 | * [Módulo](#module) 46 | * [Componentes / interfaces](#components--interfaces) 47 | * [Atributos](#attributes) 48 | * [Interface](#interface) 49 | * [Propriedades](#properties) 50 | * [Funções](#functions) 51 | * [Argumentos](#arguments) 52 | * [Anotações de função / Argumentos](#functionargument-annotations) 53 | * [Expressões de função](#function-expressions) 54 | * [Chamando funções dinamicamente](#calling-functions-dynamically) 55 | * [Importar](#import) 56 | * [Criação de objeto](#object-creation) 57 | * [Operações do sistema de arquivos](#file-system-operations) 58 | * [Diretórios](#directories) 59 | * [Arquivos](#files) 60 | * [Base de Dados](#database) 61 | * [Query](#query) 62 | * [Procedimento de armazenamento](#stored-procedure) 63 | * [Insert](#insert) 64 | * [Update](#update) 65 | * [DB Info](#db-info) 66 | * [Transações](#transactions) 67 | * [Debugging](#debugging) 68 | * [Dump](#dump) 69 | * [Log](#log) 70 | * [Trace](#trace) 71 | * [Timer](#timer) 72 | * [Geral / Diversos](#general--miscellaneous) 73 | * [Output](#output) 74 | * [Codificação de Arquivo](#file-encoding) 75 | * [Salvar Conteúdo](#save-content) 76 | * [Threading](#threading) 77 | * [Locking](#locking) 78 | * [Imagem / Manipulação XLS ](#image--xls-manipulation) 79 | * [Manipulação de PDF](#pdf-manipulation) 80 | * [Elementos de CFML baseada em tag sem implementação específica de CFScript](#elements-of-tag-based-cfml-with-no-specific-cfscript-implementation) 81 | * [Soluções baseadas em CFC](#cfc-based-solutions) 82 | * [http.cfc](#httpcfc) 83 | * [mail.cfc](#mailcfc) 84 | * [The rest](#the-rest) 85 | 86 | # Documentação CFScript 87 | 88 | Isso tenta documentar todo o CFScript, como um recurso para pessoas que estão migrando do código baseado em tag da velha escola para o código baseado em script. Estou fazendo isso porque nem o ColdFusion nem o Railo / Lucee fornecem muito (ou no caso de Railo / Lucee: _any_) útil [documentação de CFScript](https://wikidocs.adobe.com/wiki/display/coldfusionen/The+CFScript+language). 89 | 90 | Este não é um documento para converter tags em script. Não foi escrito do ponto de vista de "se você usar```` então você precisa usar [alguma construção de script] ". Ele simplesmente documenta o CFScript. 91 | 92 | Existem algumas soluções de sintaxe neutra para algumas construções CFML que estão listadas na parte inferior do documento. Estes são os CFCs encontrados em[customtag]/com/adobe/coldfusion. Estas não são construções de CFScript por si só, mas relacionadas o suficiente para serem relevantes aqui. 93 | 94 | Também não é um exercício de ensino de CFML (ou pelo menos a parte do script). Ele pressupõe que você sabe o que está fazendo e é puramente uma referência. 95 | 96 | Presumo que seja Railo 4.2 / Lucee 4.5 ou ColdFusion 11, exceto onde indicado. 97 | 98 | 99 | ### Comentários 100 | ```cfc 101 | // comentário de linha única 102 | ``` 103 | ```cfc 104 | a=1; // comentário de linha única no final da linha 105 | ``` 106 | ```cfc 107 | /* 108 | cometário 109 | de múltiplas 110 | linhas 111 | */ 112 | ``` 113 | ```cfc 114 | /* 115 | linha múltipla 116 | /* comentários */ 117 | não pode ser aninhado 118 | */ 119 | ``` 120 | 121 | Neste caso, o bit comentado é `/ * linha múltipla / * comentários * /`, tornando o próximo bit um erro de sintaxe. 122 | 123 | ### Afirmações 124 | 125 | As declarações terminam em ponto e vírgula: 126 | ```cfc 127 | a = 1; 128 | ``` 129 | Os pontos-e-vírgulas são geralmente _ opcionais no Railo / Lucee: 130 | ```cfc 131 | a = 1 132 | ``` 133 | 134 | Onde "geralmente" significa "se o final da declaração for inequívoco sem um ponto e vírgula". É melhor usar sempre ponto e vírgula. 135 | 136 | As declarações de bloco (com chaves) não têm ponto e vírgula: 137 | ```cfc 138 | while (condition) { 139 | // statements 140 | } 141 | ``` 142 | 143 | ### Variáveis 144 | 145 | Atribuindo uma variável: 146 | ```cfc 147 | varName = "foo"; 148 | ``` 149 | 150 | Atribuindo uma variável local de função: 151 | ```cfc 152 | var varName = "foo"; // analogous to local.varName = "foo"; 153 | ``` 154 | 155 | Observe que a palavra-chave var pode aparecer embutida na maioria das instruções onde uma variável é inicializada pela primeira vez, por exemplo: 156 | ```cfc 157 | for (var i=1; i <= 10; i++); 158 | ``` 159 | 160 | Atribuição de uma variável nomeada dinamicamente: 161 | ```cfc 162 | varName = "foo"; 163 | "#varName#" = "bar"; 164 | writeOutput(foo); // bar 165 | ``` 166 | ![trycf-logo] Run this example on trycf.com 167 | É o mesmo que a tag ``, mas confunde algumas pessoas por ter uma aparência um pouco estranha. Obviamente, também se pode usar a sintaxe de matriz associativa também (eg: `variables[varName] = "bar";`.Isso é preferível, pois é mais claro o que está acontecendo). 168 | 169 | Padronizando uma variável: 170 | ```cfc 171 | param numérico variableName = defaultValue; // onde "numérico" pode ser qualquer tipo 172 | ``` 173 | Para situações mais complexas: 174 | ```cfc 175 | param name = "variableName" type = "regex" pattern = "."; // qualquer atributo cfparam é compatível 176 | ``` 177 | 178 | ### Operadores 179 | 180 | Todos os operadores disponíveis para código baseado em tag ainda funcionam em CFScript. Além disso, CFScript tem estes: 181 | 182 | #### Decisão 183 | ```cfc 184 | a == 1; // igualdade 185 | a < 1; // Menor que 186 | a <= 1; // Menor ou igual 187 | a >= 1; // maior que ou igual 188 | a > 1; // Maior que 189 | a != 1; // desigualdade 190 | a <> 1; // desigualdade (apenas Railo / Lucee) 191 | ``` 192 | ![trycf-logo] Run this example on trycf.com 193 | #### Aritmética 194 | 195 | ##### Incremento-decremento 196 | ```cfc 197 | // incremento 198 | a = 1; 199 | b = a++; // b=1, a=2 // operadores pós-fixados retornam o valor e, em seguida, executam a ação (neste caso: incrementos a) 200 | c = ++a; // c=3, a=3 // operador de prefixo executa a ação e retorna o resultado 201 | ``` 202 | ```cfc 203 | // decremento 204 | a--; // a=2 205 | --a; // a=1 206 | ``` 207 | ![trycf-logo] Run this example on trycf.com 208 | ##### Atribuição-inline 209 | ```cfc 210 | a += 2; // equivalente a a=a+2 211 | a -= 3; // equivalente a a=a-3 212 | a *= 4; // equivalente a a=a*4 213 | a /= 5; // equivalente a a=a/5 214 | a %= 6; // equivalente a a=a%6 215 | s &= "a"; // equivalente a s = s & "a" 216 | ``` 217 | ![trycf-logo] Run this example on trycf.com 218 | #### Boolean 219 | ```cfc 220 | !a; // NOT a 221 | a && b; // a AND b 222 | a || b; // a OR b 223 | ``` 224 | ![trycf-logo] Run this example on trycf.com 225 | #### Decisão- 226 | 227 | ##### Operador-ternário 228 | ```cfc 229 | result = condition ? trueExpression : falseExpression; 230 | 231 | //eg: 232 | coinTossResult = randRange(0,1) ? "heads" : "tails"; 233 | ``` 234 | ![trycf-logo] Run this example on trycf.com 235 | ```cfc 236 | // NB: apenas um de trueExpression ou falseExpression é avaliado: 237 | a = 1; 238 | b = 1; 239 | c = false ? ++a : ++b; // a=1, b=2, c=2 240 | ``` 241 | ![trycf-logo] Run this example on trycf.com 242 | ##### Variação-de-coalescência-nula 243 | ```cfc 244 | result = left ?: right; //a expressão da mão esquerda é usada a menos que seja nula, caso em que a direita é usada 245 | 246 | //eg: 247 | a = d ?: "default"; // a = default 248 | ``` 249 | ![trycf-logo] Run this example on trycf.com 250 | ```cfc 251 | d = 1; 252 | a = d ?: "default"; // a = 1 253 | ``` 254 | ![trycf-logo] Run this example on trycf.com 255 | 256 | Observe que, embora pareça ser o mesmo que o operador "Elvis" de outro idioma, não é o mesmo. O operador "Elvis" verifica se há `false` (e em alguns idiomas` null` é falsey); este operador verifica especificamente por `null`. Isso provavelmente se deve a um mal-entendido por parte da Adobe (e perpetuado pelos desenvolvedores Lucee ao copiá-lo). 257 | 258 | ### Condições 259 | 260 | #### if/elseif/else 261 | ```cfc 262 | if (booleanExpression) 263 | // única instrução executada se booleanExpression for verdade 264 | else if (anotherBooleanExpression) 265 | // única instrução executada se anotherBooleanExpression for verdadeira 266 | else 267 | // única instrução executada se as condições forem falsas 268 | ``` 269 | ```cfc 270 | if (booleanExpression) { 271 | // várias instruções executadas se booleanExpression for true 272 | } else if (anotherBooleanExpression) { 273 | // várias instruções executadas se outraBooleanExpressionis true 274 | } else { 275 | // várias instruções executadas se as condições forem falsas 276 | } 277 | ``` 278 | ![trycf-logo] Run this example on trycf.com 279 | #### switch 280 | ```cfc 281 | switch (expression) { 282 | case "some constant value": // o valor pode ser dinâmico em Railo / Lucee 283 | // instruções executadas se expressão = "algum valor constante" 284 | break;// sair da instrução switch 285 | case "um valor constante diferente": 286 | // instruções executadas se expression = "um valor constante diferente" 287 | // se não houver interrupção, o processamento continua a executar as instruções até que uma interrupção seja encontrada ... 288 | // ... mas as avaliações de caso subsequentes não são feitas. Um switch é basicamente um mecanismo GOTO, que faz um ... 289 | // único GOTO o primeiro caso correspondente. NÃO é uma série de instruções if / elseif / else 290 | caso "terceiro valor constante": 291 | // instruções executadas se expressão = "um valor constante diferente" ou "terceiro valor constante" 292 | break; 293 | case "4th value": 294 | case "5th value": 295 | // instruções executadas se a expressão for um de "4º valor" ou "5º valor" 296 | break; 297 | default: 298 | // instruções executadas se nenhum caso foi atendido (ou se o último caso atendido não teve uma pausa) 299 | break; 300 | } 301 | ``` 302 | ![trycf-logo] Run this example on trycf.com 303 | #### try/catch/finally, throw/rethrow 304 | ```cfc 305 | try { 306 | // afirmações 307 | 308 | throw "message"; // lança uma exceção de aplicativo, com a mensagem fornecida 309 | 310 | // or 311 | throw (type="ExceptionType", message="message", detail="detail", errorCode="errorCode", extendedInfo="extendedInfo"); // apesar das aparências, esta NÃO é uma função 312 | 313 | // or 314 | throw (object=JavaExceptionObject); 315 | } 316 | catch (SomeExceptionType variableContainingExceptionObject) { 317 | // instruções executadas se o código em erros de bloco try com uma exceção SomeExceptionType 318 | 319 | rethrow; // rethrows the caught exception 320 | } 321 | catch (SomeOtherExceptionType variableCOntainingExceptionObject) { 322 | // instruções executadas se o código em erros de bloco try com uma exceção SomeOtherExceptionType 323 | } 324 | catch (any variableCOntainingExceptionObject) { 325 | // instruções executadas se o código em erros de bloco try com qualquer tipo de exceção ainda não detectada 326 | } 327 | finally { 328 | // instruções executadas em qualquer caso, INCLUINDO exceções não tratadas. Este código SEMPRE roda 329 | } 330 | ``` 331 | 332 | ### Iteração 333 | 334 | #### Uso-geral-para-loop 335 | ```cfc 336 | for (initialisation; condition; repetition) statement; 337 | ``` 338 | 339 | or: 340 | ```cfc 341 | for (initialisation; condition; repetition) { 342 | 343 | // afirmações 344 | } 345 | ``` 346 | 347 | EG: 348 | ```cfc 349 | for (i=1; i <=5; i++) writeOutput(i); 350 | // apenas a seguinte instrução única é repetida 351 | ``` 352 | 353 | or: 354 | ```cfc 355 | for (i=1; i <=5; i++) { 356 | // todas as instruções dentro do bloco são executadas em loop 357 | result = i * 2; 358 | writeOutput(result); 359 | } 360 | ``` 361 | 362 | A percepção geral é que esta é a única forma de um loop for () de propósito geral: inicializar uma variável de contador, testá-la e ajustá-la (incremento, decremento). Este não é o caso. Cada uma das instruções pode ser _qualquer_coisa_ (a condição precisa ser avaliada como um booleano) e, de fato, são opcionais. Este é um loop infinito, equivalente a while (true): 363 | ```cfc 364 | for (;;) 365 | ``` 366 | 367 | Um exemplo muito artificial para demonstrar a liberdade que se tem com os parâmetros do for(): 368 | ```cfc 369 | i=0; 370 | for (; true; writeOutput(i)) { 371 | if (++i > 5) break; 372 | } 373 | ``` 374 | 375 | Em geral, todas as construções de loop têm a sintaxe de instrução única ou bloco de instruções. Oferecerei apenas a sintaxe de bloco mais comum (e recomendada, para clareza de código) de agora em diante. 376 | 377 | #### Pré-condição-loop 378 | 379 | Esta forma de loop avalia uma única condição no início de cada iteração e continua em loop enquanto a condição for verdadeira: 380 | ```cfc 381 | while (condition) { 382 | // statements 383 | } 384 | ``` 385 | 386 | Esta forma de loop será executada zero ou mais vezes. 387 | 388 | #### Pós-condição-loop 389 | 390 | 391 | Esta forma de loop avalia uma única condição no início de cada iteração e continua em loop enquanto a condição para verdadeira: 392 | ```cfc 393 | do { 394 | // statements 395 | } while (condition); 396 | ``` 397 | 398 | Esta forma de loop será executada _uma_ ou mais vezes. É importante considerar que o corpo do loop sempre será executado na primeira vez, porque nenhuma condição é avaliada até o _ final_ do loop. 399 | 400 | #### Array loop 401 | 402 | ##### For statement 403 | ```cfc 404 | for (element in [1,2,3,4,5]) { 405 | writeOutput(element); // 12345 406 | } 407 | ``` 408 | 409 | ##### arrayEach() 410 | ```cfc 411 | arrayEach(["a","b","c"], function(element,index,array) { 412 | writeOutput("#index#:#element#;"); // 1:a;2:b;3:c; 413 | }); 414 | ``` 415 | 416 | ##### Array.each() 417 | ```cfc 418 | a = ["a","b","c"]; 419 | a.each(function(element,index,array) { 420 | writeOutput("#index#:#element#;"); // 1:a;2:b;3:c; 421 | }); 422 | ``` 423 | 424 | 425 | Observe que Railo / Lucee pode chamar métodos diretamente em um literal, então isso funciona: 426 | ```cfc 427 | ["a","b","c"].each(function(element,index,array) { 428 | writeOutput("#index#:#element#;"); // 1:a;2:b;3:c; 429 | }); 430 | ``` 431 | 432 | #### Struct loop 433 | 434 | ##### For statement 435 | ```cfc 436 | struct = {a=1,b=2,c=3}; 437 | for (key in struct) { 438 | writeOutput("#key#:#struct[key]#;"); // a:1;b:2;c:3; (order of keys not guaranteed, obviously) 439 | } 440 | ``` 441 | 442 | ##### structEach() 443 | ```cfc 444 | structEach(struct, function(key,value,struct) { 445 | writeOutput("#key#:#value#;"); // a:1;b:2;c:3; 446 | }); 447 | ``` 448 | 449 | ##### Struct.each() 450 | ```cfc 451 | struct.each(function(key,value,struct) { 452 | writeOutput("#key#:#value#;"); // a:1;b:2;c:3; 453 | }); 454 | ``` 455 | 456 | #### Query loop 457 | ```cfc 458 | q = queryNew("id,data", "integer,varchar",[ 459 | [11, "aa"], 460 | [22, "bb"], 461 | [33, "cc"] 462 | ]); 463 | for (row in q){ 464 | writeOutput("#q.currentRow#:#row.id#:#row.data#;"); // 1:11:aa;2:22:bb;3:33:cc; 465 | } 466 | ``` 467 | 468 | Using grouping: 469 | ```cfc 470 | q = queryNew("pk,fk,data", "integer,integer,varchar",[ 471 | [1, 10, "aa"], 472 | [2, 20, "bb"], 473 | [3, 20, "cc"], 474 | [4, 30, "dd"], 475 | [5, 30, "ee"], 476 | [6, 30, "ff"] 477 | ]); 478 | cfloop(query=q, group="fk") { 479 | writeOutput("#fk#"); 480 | cfloop() { 481 | writeOutput("#pk#:#data#
"); 482 | } 483 | writeOutput("
"); 484 | } 485 | ``` 486 | 487 | Railo/Lucee only: 488 | ```cfc 489 | loop query=q group="fk" { 490 | writeOutput("#fk#"); 491 | loop { 492 | writeOutput("#pk#:#data#
"); 493 | } 494 | writeOutput("
"); 495 | } 496 | ``` 497 | 498 | #### List loop 499 | ```cfc 500 | list = "a;b;c"; 501 | listEach(list, function(element,index,list) { 502 | writeOutput("#index#:#element#;"); // 1:a;2:b;3:c; 503 | }, ";"); 504 | 505 | // or 506 | 507 | list.each(function(element,index,list) { 508 | writeOutput("#index#:#element#;"); // 1:a;2:b;3:c; 509 | }, ";"); 510 | 511 | // or (ColdFusion only, see [RAILO-3207](https://issues.jboss.org/browse/RAILO-3207)) 512 | 513 | for (element in "a,b,c,d,e") { 514 | writeOutput(element); // abcde 515 | } 516 | ``` 517 | 518 | Não tenho certeza de como alguém especificaria um delimitador para o último exemplo: não parece compatível. 519 | 520 | Railo/Lucee only: 521 | ```cfc 522 | cfloop(list="a;b;c", index="element", delimiters=";") { 523 | writeOutput(element); // abc 524 | } 525 | 526 | // or 527 | loop list="a;b;c" index="element" delimiters=";" { 528 | writeOutput(element); // abc 529 | } 530 | ``` 531 | 532 | #### File loop 533 | ```cfc 534 | filePath = getCurrentTemplatePath(); 535 | cfloop(file=filePath, index="chars", characters=16, charset="UTF-8"){ 536 | writeOutput(chars); // outputs the contents of this file 537 | } 538 | ``` 539 | 540 | Railo/Lucee only: 541 | ```cfc 542 | loop file=filePath index="chars" characters=16 charset="UTF-8" { 543 | writeOutput(chars); 544 | } 545 | ``` 546 | 547 | #### Date/time range loop 548 | 549 | ColdFusion não tem nenhum construto específico específico de CFScript para isso a partir do ColdFusion 11 550 | 551 | Work around: 552 | ```cfc 553 | from = now(); 554 | to = dateAdd("d", 7, from); 555 | 556 | for (date=from; dateCompare(date, to, "d") <= 0; date = dateAdd("d", 1, date)) { 557 | writeOutput(dateTimeFormat(date, "yyyy-mm-dd HH:nn:sstt") & "
"); 558 | } 559 | ``` 560 | 561 | Railo/Lucee only: 562 | ```cfc 563 | cfloop(from=from, to=to, index="date", step=createTimespan(1,0,0,0)) { 564 | writeOutput(dateTimeFormat(date, "yyyy-mm-dd HH:nn:sstt") & "
"); 565 | } 566 | 567 | // or 568 | 569 | loop from=from to=to index="date" step=createTimespan(1,0,0,0) { 570 | writeOutput(dateTimeFormat(date, "yyyy-mm-dd HH:nn:sstt") & "
"); 571 | } 572 | ``` 573 | 574 | #### Iteration flow control 575 | 576 | cfcontinue: 577 | ```cfc 578 | for (i=1; i <= 5; i++) { 579 | writeOutput("#i# is "); 580 | if (i mod 2) { 581 | writeOutput("ODD
"); 582 | continue; 583 | } 584 | writeOutput("EVEN
"); 585 | } 586 | ``` 587 | 588 | ### Other flow control statements 589 | 590 | #### Request Redirect 591 | 592 | ```cfc 593 | /* cflocation */ 594 | // ColdFusion 595 | location(url="http://example.com", statuscode="301 OR 302", addtoken=false); 596 | 597 | // Railo/Lucee 598 | location url="http://example.com", statuscode="301 OR 302", addtoken=false; 599 | ``` 600 | 601 | #### Abort processing 602 | ```cfc 603 | abort; 604 | 605 | // or 606 | 607 | abort "error message"; 608 | ``` 609 | 610 | #### Exit from current file 611 | 612 | ```cfc 613 | exit; 614 | 615 | //or 616 | 617 | exit "method"; 618 | ``` 619 | 620 | ### Code reuse 621 | 622 | #### Include 623 | 624 | ```cfc 625 | include "pathToFile"; 626 | 627 | // or 628 | 629 | include "pathToFile" runonce=true; 630 | ``` 631 | 632 | #### Module 633 | 634 | ```cfc 635 | // Railo/Lucee 636 | module template="inc.cfm" attr1="val1" attr2="val2"; 637 | 638 | // ColdFusion 639 | cfmodule(template="inc.cfm", attr1="val1", attr2="val2"); 640 | ``` 641 | 642 | ### Components / interfaces 643 | 644 | ```cfc 645 | component { 646 | 647 | } 648 | ``` 649 | 650 | #### Attributes 651 | ```cfc 652 | component extends="Parent" { 653 | 654 | } 655 | ``` 656 | 657 | Or: 658 | 659 | ```cfc 660 | /** 661 | * @extends Parent 662 | */ 663 | component { 664 | 665 | } 666 | ``` 667 | 668 | 669 | Observe que o comentário para anotações é `/ **` não simplesmente `/ *`. 670 | 671 | 672 | Observe também que a última sintaxe não funciona atualmente no Railo (consulte [RAILO-3169] (https://issues.jboss.org/browse/RAILO-3169)). 673 | 674 | #### Interface 675 | 676 | ```cfc 677 | interface { 678 | public void function f(required numeric x); // observe que não há colchetes e termina com ponto e vírgula 679 | } 680 | ``` 681 | 682 | #### Properties 683 | 684 | Básico: 685 | 686 | ```cfc 687 | property string myProperty; 688 | ``` 689 | 690 | Com parâmetros adicionais: 691 | 692 | ```cfc 693 | property type="string" name="myProperty" default="default value"; // and all the same attributes as `` 694 | ``` 695 | 696 | #### Functions 697 | 698 | Básico: 699 | 700 | ```cfc 701 | function f() { // assumes public function, returntype any 702 | 703 | } 704 | ``` 705 | 706 | Com modificadores de tipo de acesso e retorno: 707 | 708 | ```cfc 709 | private void function f() { 710 | // statements 711 | } 712 | ``` 713 | 714 | #### Arguments 715 | 716 | Basic: 717 | ```cfc 718 | function f(x) { // optional argument of type "any" 719 | //afirmações 720 | } 721 | ``` 722 | 723 | Type: 724 | ```cfc 725 | function f(numeric x) { // optional argument of type "numeric" 726 | //afirmações 727 | } 728 | ``` 729 | Required: 730 | ```cfc 731 | function f(required numeric x) { // required argument of type "numeric" 732 | // afirmações 733 | } 734 | ``` 735 | Default value: 736 | ```cfc 737 | function f(numeric x = 0) { // optional argument of type "numeric" with default value of 0 738 | // afirmações 739 | } 740 | ``` 741 | 742 | #### Function/argument annotations 743 | ```cfc 744 | /** 745 | * @x.hint hint for argument x 746 | * @x.type numeric 747 | * @x.required true 748 | */ 749 | function f(x) { 750 | // afirmações 751 | } 752 | ``` 753 | 754 | Note these annotations do not current correctly work on Railo (see [RAILO-3170](https://issues.jboss.org/browse/RAILO-3170)) 755 | 756 | Also note that this does not currently work on ColdFusion (see [3808960](https://bugbase.adobe.com/index.cfm?event=bug&id=3808960)) 757 | ```cfc 758 | /** 759 | * @x.type numeric 760 | * @x.default 0 // this causes a compile error 761 | */ 762 | function f(x) { 763 | // afirmações 764 | } 765 | ``` 766 | 767 | #### Function expressions 768 | ```cfc 769 | f = function(x) { 770 | // afirmações 771 | }; 772 | ``` 773 | 774 | Funções definidas por expressões de função usam fechamento, funções definidas por uma declaração de função não 775 | 776 | Annotations for function expressions are not supported on ColdFusion ([3808978](https://bugbase.adobe.com/index.cfm?event=bug&id=3808978)); are supported on Railo, but have same shortcomings as noted above. 777 | 778 | #### Calling functions dynamically 779 | ```cfc 780 | test = new Test(); 781 | methodToCall = "f"; 782 | argumentsToPass = {x=1}; 783 | result = invoke(test, methodToCall, argumentsToPass); 784 | ``` 785 | 786 | Railo/Lucee-only: 787 | ```cfc 788 | result = test[methodToCall](argumentCollection=argumentsToPass); 789 | ``` 790 | 791 | #### Import 792 | ```cfc 793 | import com.domain.app.package.*; 794 | ``` 795 | 796 | #### Object creation 797 | ```cfc 798 | myObj = createObject(type, "path.to.class"); // along with other type/situation-specific arguments 799 | 800 | // or 801 | 802 | myObj = new path.to.some.cfc.file(); // NB: will call the CFC's init() (by default), or method identified by the initmethod attribute of the component (bug in Railo: [RAILO-2294](https://issues.jboss.org/browse/RAILO-2294)) 803 | ``` 804 | 805 | ### File system operations 806 | 807 | #### Directories 808 | ```cfc 809 | 810 | // criação de diretório simples 811 | directoryCreate("path/to/directory"); 812 | ``` 813 | ```cfc 814 | // usando outros atributos opcionais 815 | cfdirectory(action="create", directory="path/to/directory", mode="777"); 816 | ``` 817 | ```cfc 818 | // Railo/Lucee only 819 | directory action="create" directory="path/to/directory" mode="777"; 820 | ``` 821 | ```cfc 822 | // excluir 823 | 824 | directoryDelete("path/to/directory"); 825 | ``` 826 | ```cfc 827 | // Lista 828 | listing = directoryList("path/to/directory", true, "query", "*.cfm", "size desc"); // CF11 added an additional "type" attribute. Not currently supported on Railo/Lucee 829 | ``` 830 | ```cfc 831 | // renomear 832 | directoryRename("path/to/directory", "path/to/new/directory"); 833 | ``` 834 | 835 | #### Arquivo 836 | ```cfc 837 | // read 838 | // text 839 | if (fileExists("path/to/file")) { 840 | result = fileRead("path/to/file"); 841 | } 842 | 843 | // ou 844 | fileHandle = fileOpen("path/to/file", "read"); 845 | result = fileRead(fileHandle, bytesToRead); 846 | fileClose(fileHandle); 847 | 848 | // ou 849 | fileHandle = fileOpen("path/to/file", "read"); 850 | while (!fileIsEOF(fileHandle)) { 851 | result = fileReadLine(fileHandle); 852 | } 853 | fileClose(fileHandle); 854 | 855 | ``` 856 | ```cfc 857 | // binário 858 | 859 | result = fileReadBinary("path/to/file"); 860 | 861 | //ou 862 | fileHandle = fileOpen("path/to/file", "readbinary"); 863 | result = fileRead(fileHandle, bytesToRead); 864 | ``` 865 | ```cfc 866 | // acrescentar 867 | fileHandle = fileOpen("path/to/file", "append"); 868 | fileWrite(fileHandle, textToAppend); 869 | fileClose(fileHandle); 870 | ``` 871 | ```cfc 872 | // cópia 873 | fileCopy("path/to/file", "path/to/copyOfFile"); 874 | ``` 875 | ```cfc 876 | // deletar 877 | fileDelete("path/to/file"); 878 | ``` 879 | ```cfc 880 | // mover / renomear 881 | fileMove("path/to/file", "new/path/to/file"); 882 | ``` 883 | ```cfc 884 | // upload 885 | fileUpload("path/to/upload/file/to"); 886 | fileUpload(destination [, fileField [, accept [, nameConflict]]]); 887 | 888 | fileUploadAll("path/to/upload/files/to"); 889 | fileUploadAll(destination [, fileField [, accept [, nameConflict]]]); 890 | ``` 891 | ```cfc 892 | // Escrever 893 | fileWrite("path/to/file", data); 894 | 895 | // ou 896 | 897 | fileWrite(fileHandle, data); 898 | ``` 899 | 900 | ### Database 901 | 902 | #### Query 903 | ```cfc 904 | // Forma geral 905 | recordset = queryExecute(sqlString, params, options); 906 | ``` 907 | ```cfc 908 | // com array params 909 | numbers = queryExecute(" 910 | SELECT columns 911 | FROM table 912 | WHERE id BETWEEN ? AND ? 913 | ", 914 | [1,4], 915 | { 916 | datasource ="myDsn", 917 | result = "result" // this is analogous to the result attribute of `` 918 | }); 919 | ``` 920 | ```cfc 921 | // com estrutura params 922 | numbers = queryExecute(" 923 | SELECT columns 924 | FROM table 925 | WHERE id BETWEEN :low AND :high 926 | ",{low=2,high=3}); 927 | ``` 928 | 929 | Para qualificar parâmetros com tipos SQL, você pode especificar o equivalente das opções cfqueryparam com os parâmetros da seguinte maneira: 930 | 931 | ```cfc 932 | // com tipos sql na estrutura params 933 | numbers = queryExecute(" 934 | SELECT columns 935 | FROM table 936 | WHERE id BETWEEN :low AND :high 937 | ", 938 | { 939 | low = { value = 2, 940 | cfsqltype = "cf_sql_integer" 941 | }, 942 | high = { value = 3, 943 | cfsqltype = "cf_sql_integer" 944 | } 945 | }); 946 | ``` 947 | 948 | Para versões anteriores ao ColdFusion 11 (em que queryExecute () foi implementado), existe uma solução baseada em CFC: [Query.cfc](https://wikidocs.adobe.com/wiki/display/coldfusionen/query). An example is as follows: 949 | ```cfc 950 | numbers = new Query( 951 | sql = " 952 | SELECT columns 953 | FROM table 954 | WHERE id BETWEEN :low AND :high 955 | ", 956 | parameters =[ 957 | {name="low", value=2}, 958 | {name="high", value=3} 959 | ] 960 | ).execute().getResult(); 961 | ``` 962 | 963 | #### Stored Procedure 964 | ```cfc 965 | cfstoredproc(procedure="procName") { 966 | cfprocparam(type="in", cfsqltype="cf_sql_varchar", value="someValue"); 967 | cfprocresult(name="result",resultSet=1); 968 | cfprocresult(name="result2",resultSet=2); 969 | } 970 | ``` 971 | 972 | Railo/Lucee only 973 | ```cfc 974 | storedproc procedure="procName" 975 | dataSource = "myDataSource" 976 | result="response" 977 | returncode="true" { 978 | procparam type="in" cfsqltype="cf_sql_varchar" value="someValue"; 979 | procparam type="out" cfsqltype="cf_sql_integer" variable="myVariable"; 980 | procresult resultSet=1 name="result"; 981 | procresult resultSet=2 name="result2"; 982 | } 983 | ``` 984 | 985 | Há uma solicitação de mudança na qual você deve votar para implementar esta sintaxe: 986 | ```cfc 987 | options = { 988 | datasource = "scratch_mssql", 989 | fetchclientinfo = true, 990 | returncode = true 991 | }; 992 | params = [ 993 | {value=URL.low, type="INTEGER"}, 994 | {value=URL.high, type="INTEGER"}, 995 | {type="out", variable="inclusiveCount", type="INTEGER"}, 996 | {type="out", variable="exclusiveCount", type="INTEGER"} 997 | ]; 998 | 999 | result = executeProcedure("uspGetColours", params, options); 1000 | ``` 1001 | 1002 | See ColdFusion ticket: [3791737](https://bugbase.adobe.com/index.cfm?event=bug&id=3791737); Railo ticket: [RAILO-3184](https://issues.jboss.org/browse/RAILO-3184), and earlier blog article: '[ColdFusion 11: calling a stored procedure from script. And can we please stop wearing out our "c" and "f" keys?](http://blog.adamcameron.me/2014/03/coldfusion-11-calling-stored-procedure.html#executeProcedure)'. 1003 | 1004 | #### Insert 1005 | 1006 | Railo/Lucee only: 1007 | ```cfc 1008 | insert datasource="myDataSource" tableName="myTable" formFields="list,of,form,fields"; // arguments the same as ``. datasource is optional 1009 | ``` 1010 | 1011 | Note: there is a bug with this: [RAILO-3180](https://issues.jboss.org/browse/RAILO-3180). 1012 | 1013 | ColdFusion only: 1014 | ```cfc 1015 | cfinsert(datasource="myDataSource", tableName="myTable", formFields="list,of,form,fields"); // arguments the same as `` 1016 | ``` 1017 | 1018 | Observe que a fonte de dados é necessária no momento, o que é um bug:[3814079](https://bugbase.adobe.com/index.cfm?event=bug&id=3814079). 1019 | 1020 | #### Update 1021 | 1022 | Railo/Lucee only: 1023 | ```cfc 1024 | update datasource="myDataSource" table="myTable" formFields="list,of,form,fields"; // arguments the same as ``. datasource is optional 1025 | ``` 1026 | 1027 | Observe que o mesmo bug se aplica aqui como acontece com o insert. 1028 | 1029 | ColdFusion only: 1030 | ```cfc 1031 | cfupdate(datasource="myDataSource", table="myTable", formFields="list,of,form,fields"); // arguments the same as `` 1032 | ``` 1033 | 1034 | #### DB Info 1035 | ```cfc 1036 | cfdbinfo(type="tables", name="info"); // arguments the same as `` 1037 | ``` 1038 | 1039 | Railo/Lucee only: 1040 | ```cfc 1041 | dbinfo type="tables" name="info"; // arguments the same as `` 1042 | ``` 1043 | 1044 | #### Transactions 1045 | ```cfc 1046 | transaction { 1047 | try { 1048 | // stuff to do 1049 | transaction action="commit"; 1050 | } 1051 | catch (any e) { 1052 | transaction action="rollback"; 1053 | } 1054 | } 1055 | ``` 1056 | Observe que todos os atributos de `` são suportados como pares nome / valor separados por espaço. 1057 | 1058 | ### Debugging 1059 | 1060 | #### Dump 1061 | ```cfc 1062 | writeDump(myVar); // can use either ordered or named arguments. 1063 | ``` 1064 | 1065 | Com argumentos nomeados: 1066 | ```cfc 1067 | writeDump(var=myVar, output=ExpandPath('/debug/log.txt')); 1068 | ``` 1069 | 1070 | Railo/Lucee only: 1071 | ```cfc 1072 | dump(myVar) 1073 | ``` 1074 | 1075 | #### Log 1076 | ```cfc 1077 | writeLog("text to log"); // pode usar argumentos ordenados ou nomeados. 1078 | ``` 1079 | 1080 | #### Trace 1081 | ```cfc 1082 | // Railo/Lucee only 1083 | trace category="test" text="trace text" { // mais todos os mesmos parâmetros que `` 1084 | // coisas para rastrear 1085 | } 1086 | ``` 1087 | ```cfc 1088 | // COLDFUSION only 1089 | trace(category="test", text="trace text") { // mais todos os mesmos parâmetros que `` 1090 | // coisas para rastrear 1091 | } 1092 | // note that CF11 incorrectly records timing information (see [3811003](https://bugbase.adobe.com/index.cfm?event=bug&id=3811003)) 1093 | ``` 1094 | 1095 | #### Timer 1096 | ```cfc 1097 | cftimer(label="timer label" type="outline") { // mais todos os mesmos parâmetros que `` 1098 | // coisas ao tempo 1099 | } 1100 | ``` 1101 | ```cfc 1102 | // Railo/Lucee only 1103 | timer label="timer label" type="outline" { // mais todos os mesmos parâmetros que `` 1104 | // coisas ao tempo 1105 | } 1106 | ``` 1107 | 1108 | ### General / Miscellaneous 1109 | 1110 | #### Output 1111 | ```cfc 1112 | writeOutput(expression); // expressão deve ser resolvida em uma string 1113 | ``` 1114 | 1115 | Railo/Lucee only: 1116 | ```cfc 1117 | echo(expression); // expressão deve ser resolvida em uma string 1118 | ``` 1119 | 1120 | #### File Encoding 1121 | ```cfc 1122 | pageencoding "UTF-8"; 1123 | ``` 1124 | 1125 | Observe que isso só funciona em arquivos CFC no ColdFusion ([3712167](https://bugbase.adobe.com/index.cfm?event=bug&id=3712167)). Funciona corretamente no Railo / Lucee. 1126 | 1127 | #### Save content 1128 | ```cfc 1129 | savecontent variable="saved" { 1130 | writeOutput("stuff to save"); 1131 | } 1132 | ``` 1133 | 1134 | #### Threading 1135 | ```cfc 1136 | thread action="run" name="threadName" { 1137 | // código a ser executado em um tópico separado aqui 1138 | } 1139 | thread action="join" name="threadName,anotherThreadName"; 1140 | ``` 1141 | 1142 | #### Locking 1143 | ```cfc 1144 | lock name="lockName" timeout=1 throwontimeout=true { 1145 | // código para bloquear 1146 | } 1147 | ``` 1148 | 1149 | #### Image / XLS manipulation 1150 | 1151 | Os equivalentes de função de [``](https://wikidocs.adobe.com/wiki/display/coldfusionen/Image+functions) and [``](https://wikidocs.adobe.com/wiki/display/coldfusionen/Spreadsheet+functions) estão todos bem documentados e não são especificamente construções de CFScript. 1152 | 1153 | #### PDF Manipulation 1154 | 1155 | Devo admitir que nunca fiz nenhum trabalho com PDFs, portanto, não posso fazer comentários informados sobre os equivalentes do CFScript. No entanto, em vez de construções específicas específicas do CFScript que conheço, a sintaxe genérica deve funcionar, por exemplo: 1156 | 1157 | ColdFusion: 1158 | ```cfc 1159 | cfdocument(format="PDF") { 1160 | // marcação aqui 1161 | } 1162 | ``` 1163 | Railo/Lucee: 1164 | ```cfc 1165 | document format="PDF" { 1166 | // marcação aqui 1167 | } 1168 | ``` 1169 | 1170 | O mesmo deve funcionar em outras tags orientadas a PDF. Para versões do ColdFusion anteriores ao CF11, existe um PDF.cfc (semelhante ao Query.cfc, e também em cfusion / CustomTags / com / adobe / coldfusion). Nunca usei, não sei como funciona e não tenho interesse em descobrir. Se alguém quiser doar algum código de exemplo, irei integrá-lo aqui. 1171 | 1172 | 1173 | ### Elements of tag-based CFML with no _specific_ CFScript implementation 1174 | 1175 | #### CFC-based solutions 1176 | 1177 | Pelo que eu posso dizer, não há implementações específicas de CFScript para as seguintes peças de funcionalidade: 1178 | * `` 1179 | * `` 1180 | * `` 1181 | * `` 1182 | * `` 1183 | * `` 1184 | * `` 1185 | * `` 1186 | 1187 | Existem wrappers CFC para estes em cfusion / CustomTags / com / adobe / coldfusion. Essas não são soluções específicas do CFScript em si - pode-se usá-las com a mesma facilidade em código baseado em tag - mas podem ser incluídas aqui para fins de integridade. Eu pessoalmente não uso essas construções e, como não fazem parte do CFScript, não tentei incluí-las aqui. Sinta-se à vontade para documentar e incluí-los, se desejar. 1188 | 1189 | #### http.cfc 1190 | 1191 | ColdFusion (CF9+): 1192 | 1193 | __The pattern seems to be `set{ATTRIBUTENAME}( value );` for setting attributes that are normally set via the `` tag__ 1194 | 1195 | ```cfc 1196 | //há um CFC embutido que lida com isso no CF9 + 1197 | httpService = new http(); 1198 | httpService.setMethod( "post" ) 1199 | httpService.setCharset( "utf-8" ); 1200 | 1201 | //o provedor de API pode exigir que você exporte este certificado 1202 | // então você precisará salvá-lo em um lugar seguro ... 1203 | // e referenciá-lo aqui 1204 | httpService.setClientCert( "#ExpandPath(‘.’)#/my_cert.p12" ); 1205 | httpService.setClientCertPassword( "mypassword!" ); 1206 | httpService.setUrl( "https://api.sample.com/" ); 1207 | 1208 | //esses parâmetros são campos de formulário para POST 1209 | httpService.addParam(type="formfield", name="field1", value="1111"); 1210 | httpService.addParam(type="formfield", name="field2", value="some text here"); 1211 | 1212 | //esta é a maneira cfscript de obter a resposta 1213 | httpResponse = httpService.send().getPrefix(); 1214 | 1215 | writeDump(httpResponse); 1216 | ``` 1217 | 1218 | #### mail.cfc 1219 | 1220 | ColdFusion (CF9+): 1221 | 1222 | __The pattern seems to be `set{ATTRIBUTENAME}( value );` for setting attributes that are normally set via the `` tag__ 1223 | 1224 | ```cfc 1225 | mailerService = new mail(); 1226 | /* definir atributos de e-mail usando configuradores implícitos fornecidos * / 1227 | mailerService.setType("html"); 1228 | mailerService.setCharset( "utf-8" ); 1229 | mailerService.setTo( "adam@sample.com" ); 1230 | mailerService.setFrom( "test@sample.com;joe@sample.com" ); 1231 | mailerService.setSubject( "Super interesting subject" ); 1232 | 1233 | /* add mailparams */ 1234 | mailerService.addParam( file=expandpath(form.attachment), type="text/plain", remove=false ); 1235 | // create the body 1236 | savecontent variable="mailBody"{ 1237 | WriteDump( CGI ); 1238 | WriteDump( SESSION ); 1239 | } 1240 | // envie o email 1241 | mailerService.send( body=mailBody ); 1242 | ``` 1243 | 1244 | 1245 | #### The rest 1246 | 1247 | 1248 | Para usar qualquer outra funcionalidade não listada aqui no CFScript, é necessário usar a sintaxe generalizada. 1249 | 1250 | Em Railo / Lucee, é uma questão de remover o "` ` ", e usar a sintaxe de bloco normal (chaves) onde a versão da tag é uma tag orientada a blocos. 1251 | 1252 | No ColdFusion (CF11 +), substitua "` ` "por" `)` ", e separe os atributos por vírgulas. Observe que isso fará com que a construção _pareça_ com uma função, mas na verdade não é e não pode ser usada como uma função, por exemplo, esta é uma sintaxe inválida: 1253 | 1254 | ```cfc 1255 | result = cfhttp(method="post", url="http://example.com"); 1256 | ``` 1257 | 1258 | Algumas tags possuem um bloco de código / texto dentro delas. Os blocos são representados com chaves, semelhantes a uma instrução de controle de fluxo. 1259 | 1260 | ```cfc 1261 | cfmail(attributeCollection = attributesforCfmail) { 1262 | cfmailpart(type="text/plain") { 1263 | writeOutput("Se estiver vendo isso, seu cliente de e-mail não oferece suporte a mensagens em HTML. "); 1264 | ); 1265 | } 1266 | cfmailpart(type="text/html") { 1267 | writeOutput(htmlVersionOfMessage); 1268 | } 1269 | } 1270 | 1271 | ``` 1272 | 1273 | Observe como o texto precisa ser "produzido" usando `writeOutput`. Observe também como as sub-tags (`cfmailpart` aqui) também são expressas usando as mesmas regras das tags-pai. 1274 | 1275 | * * * 1276 | 1277 | [![Creative Commons License](https://i.creativecommons.org/l/by/4.0/88x31.png)](http://creativecommons.org/licenses/by/4.0/) 1278 | This work is licensed under a [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/). 1279 | 1280 | [trycf-logo]: http://trycf.com/img/trycf-logo-tiny.png "TryCF.com" 1281 | -------------------------------------------------------------------------------- /licence.md: -------------------------------------------------------------------------------- 1 | [![Creative Commons 2 | Licence](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)](http://creativecommons.org/licenses/by-sa/4.0/)\ 3 | CFScript documentation by [Adam 4 | Cameron](https://github.com/adamcameron/cfscript/blob/master/cfscript.md) 5 | is licensed under a [Creative Commons Attribution-ShareAlike 4.0 6 | International License](http://creativecommons.org/licenses/by-sa/4.0/). 7 | --------------------------------------------------------------------------------